diff --git a/CHANGELOG.md b/CHANGELOG.md
index 16ed020f1e1c862ec4b1b8f8489a7f5e6596d8ba..4112fa4a01dedee365bbdcc83eb037be4fc7d4a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,83 @@
+2.0.0.0-dev87
+=============
+* Service layer updates:
+  * Created Tax Calculation service
+  * Implemented search Tax Rates(search criteria) in TaxRate service
+  * Refactored Tax Helper to use Tax Service
+  * Validated and ensured that after helper fix, all modules with cross-dependencies use Tax Services
+  * Refactored Bundle, Catalog, Checkout, Customer, Downloadable, Review, Logging Modules to use Tax Services
+  * Refactored Internal Tax Module Blocks/Templates to use Tax Services
+* GitHub requests:
+  * [#579] (https://github.com/magento/magento2/pull/579) -- update GA code from ga.js to analytics.js
+  * [#584] (https://github.com/magento/magento2/issues/584) -- Merge and minify js - Exception
+  * [#585] (https://github.com/magento/magento2/pull/585) -- Add forgotten return statement
+  * [#592] (https://github.com/magento/magento2/issues/592) -- Module name pattern
+* Tax calculation updates:
+  * Separate and display Weee line item totals from Tax
+* Fixed bugs:
+  * Fixed an issue when Custom attribute template was not applied to a product  during product creation
+  * Fixed an issue when report grid with no results contained unnecessary empty "total" section
+  * Fixed an issue where MCRYPT_RIJNDAEL_128 Cipher was set instead of 256 version
+  * Fixed an issue when inline translate script was always included in the page even if it was not used
+  * Fixed an issue where URL Generation was affected by previously processed URLs
+  * Fixed an issue with cross-site scripting vulnerability via cookie exploitation
+  * Fixed an issue with incorrect success message after system variable was deleted
+  * Fixed an issue with category page not opening if it had bundle product with fixed price assigned to it
+  * Fixed an issue when subtotal price in a shopping cart was not updated if the product qty is changed
+  * Fixed an issue when syntax error appeared while creating new Google Content attribute mapping
+  * Fixed an issue with JS error when adding associated simple product to the grouped one
+  * Fixed an issue with incorrect items label for the cases when there are more than one item in the category
+  * Fixed an issue when configurable product was out of stock in Google Shopping while being in stock in the Magento backend
+  * Fixed an issue when swipe gesture in menu widget was not supported on mobile
+  * Fixed an issue when it was impossible to enter alpha-numeric zip code on the stage of  estimating shipping and tax rates
+  * Fixed an issue when it was impossible to edit gift card account
+  * Fixed an issue when custom price was not applied when editing an order
+  * Fixed an issue when  items were  not returned to stock after unsuccessful order was placed
+  * Fixed an issue when error message appeared "Cannot save the credit memo” while creating credit memo
+  * Fixed an issue when Catalog price rule was not shown for the product if price was less than a discount
+* Indexer implementation:
+  * Implemented a new Stock indexer
+  * Implemented a new EAV indexer
+  * Fixed failed L1 plan on phpunit 4.1.0
+  * Minor updates for integration test framework
+  * Split action controllers classes into action classes
+  * Added public MTF repository to the packagist.org
+* Added the following functional tests:
+  * Create Admin User
+  * Create Category
+  * Create Custom Url Rewrite
+  * Create Frontend Product Review
+  * Delete CMS Page
+  * Delete Product
+  * Delete System Variable
+  * Update Admin User Role
+  * Update Product Review
+* Indexer-less implementation of URL Rewrites functionality in new UrlRedirect module:
+  * Ported Admin UI from old UrlRewrite module
+  * Implemented URL Rewrites unified storage
+* Covered the following Magento application components with unit tests:
+  * `Magento/Bundle/Block/Sales/Order/Items/Renderer.php`
+  * `Magento/Bundle/Helper/Catalog/Product/Configuration.php`
+  * `Magento/Bundle/Helper/Data.php`
+  * `Magento/Bundle/Model/Option.php`
+  * `Magento/Bundle/Model/Plugin/PriceBackend.php`
+  * `Magento/Bundle/Model/Product/Attribute/Source/Price/View.php`
+  * `Magento/Bundle/Model/Sales/Order/Pdf/Items/AbstractItems.php`
+  * `Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Enabled.php`
+  * `Magento/Catalog/Model/Product/Attribute/Source/Msrp/Type/Price.php`
+  * `Magento/Catalog/Model/Product/Visibility.php`
+  * `Magento/Eav/Model/Entity/Attribute/AbstractAttribute.php`
+  * `Magento/Eav/Model/Entity/Attribute/Source/AbstractSource.php`
+  * `Magento/Eav/Model/Entity/Attribute/Source/Boolean.php`
+  * `Magento/Eav/Model/Entity/Attribute/Source/Table.php`
+  * `Magento/Tax/Model/TaxClass/Source/Product.php`
+* Covered Magento library with unit tests :
+  * `lib/internal/Magento/Framework/Simplexml/Config/Cache/AbstractCache.php`
+  * `lib/internal/Magento/Framework/Simplexml/Config.php`
+  * `lib/internal/Magento/Framework/Stdlib/DateTime/DateTime.php`
+  * `lib/internal/Magento/Framework/Stdlib/DateTime/Timezone.php`
+  * `lib/internal/Magento/Framework/Stdlib/String.php`
+
 2.0.0.0-dev86
 =============
 * Service layer updates:
@@ -46,8 +126,8 @@
   * Fixed issues with  the translate and the logging transformation tools
   * Fixed an issue where it was impossible to create a URL rewrite for a CMS Page with Temporary (302) or Permanent (301) redirect
 * GitHub requests:
-  * [#598] Add Sort Order to Rules
-  * [#580] Set changed status on model to prevent status overwriting when model gets saved
+  * [#598] (https://github.com/magento/magento2/pull/598) -- Add Sort Order to Rules
+  * [#580] (https://github.com/magento/magento2/pull/580) -- Set changed status on model to prevent status overwriting when model gets saved
 * Unit Tests Coverage:
   * Part of the Catalog module covered with the unit tests
 * Added the following functional tests:
@@ -81,7 +161,7 @@
   * Created ProductsCustomOptions Service API for Catalog module
   * Created DownloadableLink Service API for Catalog module
 * GitHub requests:
-  * [#257] JSON loading should follow OWASP recommendation
+  * [#257] (https://github.com/magento/magento2/issues/257) -- JSON loading should follow OWASP recommendation
 
 2.0.0.0-dev84
 =============
@@ -102,8 +182,8 @@
   * Fixed an issue where an admin could search product by attributes set on the Store View level (except default store view)
   * Fixed an issue where extra spaces in search values were not ignored during search and thus wrong search results were given
 * GitHub requests:
-  * [#542]  Fix ImportExport bug which occurs while importing multiple rows per entity
-  * [#544]  Performance tests not working
+  * [#542] (https://github.com/magento/magento2/pull/542) -- Fix ImportExport bug which occurs while importing multiple rows per entity
+  * [#544] (https://github.com/magento/magento2/issues/544) -- Performance tests not working
 * Framework improvements:
   * Covered the following Magento application components with unit tests:
       * `Customer/Model/Address.php`
diff --git a/app/code/Magento/AdminNotification/Block/Inbox.php b/app/code/Magento/AdminNotification/Block/Inbox.php
index 645964d0e473496c4fd11421a5b89fb1265c0595..104c5e718d0f82295e442919ea02dcc8e953b4ff 100644
--- a/app/code/Magento/AdminNotification/Block/Inbox.php
+++ b/app/code/Magento/AdminNotification/Block/Inbox.php
@@ -36,6 +36,6 @@ class Inbox extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_AdminNotification';
         $this->_headerText = __('Messages Inbox');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php
index 1ea1f1c1741fec336e5d1e7999a737dd1a502f25..c6314755d1479e949891f27b1d62a0c3d2ae61ca 100644
--- a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification.php
@@ -27,163 +27,6 @@ namespace Magento\AdminNotification\Controller\Adminhtml;
 
 class Notification extends \Magento\Backend\App\AbstractAction
 {
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Notifications'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_AdminNotification::system_adminnotification'
-        )->_addBreadcrumb(
-            __('Messages Inbox'),
-            __('Messages Inbox')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function markAsReadAction()
-    {
-        $notificationId = (int)$this->getRequest()->getParam('id');
-        if ($notificationId) {
-            try {
-                $this->_objectManager->create(
-                    'Magento\AdminNotification\Model\NotificationService'
-                )->markAsRead(
-                    $notificationId
-                );
-                $this->messageManager->addSuccess(__('The message has been marked as Read.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __("We couldn't mark the notification as Read because of an error.")
-                );
-            }
-
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            return;
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Mark notification as read (AJAX action)
-     *
-     * @return void
-     */
-    public function ajaxMarkAsReadAction()
-    {
-        if (!$this->getRequest()->getPost()) {
-            return;
-        }
-        $notificationId = (int)$this->getRequest()->getPost('id');
-        $responseData = array();
-        try {
-            $this->_objectManager->create(
-                'Magento\AdminNotification\Model\NotificationService'
-            )->markAsRead(
-                $notificationId
-            );
-            $responseData['success'] = true;
-        } catch (\Exception $e) {
-            $responseData['success'] = false;
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->create('Magento\Core\Helper\Data')->jsonEncode($responseData)
-        );
-    }
-
-    /**
-     * @return void
-     */
-    public function massMarkAsReadAction()
-    {
-        $ids = $this->getRequest()->getParam('notification');
-        if (!is_array($ids)) {
-            $this->messageManager->addError(__('Please select messages.'));
-        } else {
-            try {
-                foreach ($ids as $id) {
-                    $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
-                    if ($model->getId()) {
-                        $model->setIsRead(1)->save();
-                    }
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 record(s) have been marked as Read.', count($ids))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __("We couldn't mark the notification as Read because of an error.")
-                );
-            }
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function removeAction()
-    {
-        if ($id = $this->getRequest()->getParam('id')) {
-            $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
-
-            if (!$model->getId()) {
-                $this->_redirect('adminhtml/*/');
-                return;
-            }
-
-            try {
-                $model->setIsRemove(1)->save();
-                $this->messageManager->addSuccess(__('The message has been removed.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __("We couldn't remove the messages because of an error."));
-            }
-
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function massRemoveAction()
-    {
-        $ids = $this->getRequest()->getParam('notification');
-        if (!is_array($ids)) {
-            $this->messageManager->addError(__('Please select messages.'));
-        } else {
-            try {
-                foreach ($ids as $id) {
-                    $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
-                    if ($model->getId()) {
-                        $model->setIsRemove(1)->save();
-                    }
-                }
-                $this->messageManager->addSuccess(__('Total of %1 record(s) have been removed.', count($ids)));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __("We couldn't remove the messages because of an error."));
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
 
     /**
      * @return bool
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/AjaxMarkAsRead.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/AjaxMarkAsRead.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c4db70b9189381e12fc6114868d39a311566532
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/AjaxMarkAsRead.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class AjaxMarkAsRead extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * Mark notification as read (AJAX action)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->getRequest()->getPost()) {
+            return;
+        }
+        $notificationId = (int)$this->getRequest()->getPost('id');
+        $responseData = array();
+        try {
+            $this->_objectManager->create(
+                'Magento\AdminNotification\Model\NotificationService'
+            )->markAsRead(
+                $notificationId
+            );
+            $responseData['success'] = true;
+        } catch (\Exception $e) {
+            $responseData['success'] = false;
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->create('Magento\Core\Helper\Data')->jsonEncode($responseData)
+        );
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Index.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..42a008062d3172a4a181aa0c3f48982b6a721645
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Index.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class Index extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Notifications'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_AdminNotification::system_adminnotification'
+        )->_addBreadcrumb(
+            __('Messages Inbox'),
+            __('Messages Inbox')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MarkAsRead.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MarkAsRead.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3c2d13c2ec73563eea299161c2ab239f4f6d0f0
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MarkAsRead.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class MarkAsRead extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $notificationId = (int)$this->getRequest()->getParam('id');
+        if ($notificationId) {
+            try {
+                $this->_objectManager->create(
+                    'Magento\AdminNotification\Model\NotificationService'
+                )->markAsRead(
+                    $notificationId
+                );
+                $this->messageManager->addSuccess(__('The message has been marked as Read.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __("We couldn't mark the notification as Read because of an error.")
+                );
+            }
+
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+            return;
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassMarkAsRead.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassMarkAsRead.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a48e8822e5e1f6b566b95b683390b12d6da7237
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassMarkAsRead.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class MassMarkAsRead extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $ids = $this->getRequest()->getParam('notification');
+        if (!is_array($ids)) {
+            $this->messageManager->addError(__('Please select messages.'));
+        } else {
+            try {
+                foreach ($ids as $id) {
+                    $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
+                    if ($model->getId()) {
+                        $model->setIsRead(1)->save();
+                    }
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 record(s) have been marked as Read.', count($ids))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __("We couldn't mark the notification as Read because of an error.")
+                );
+            }
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php
new file mode 100644
index 0000000000000000000000000000000000000000..7584d9de8234b69fb696f4a536cf8d535548df42
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/MassRemove.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class MassRemove extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $ids = $this->getRequest()->getParam('notification');
+        if (!is_array($ids)) {
+            $this->messageManager->addError(__('Please select messages.'));
+        } else {
+            try {
+                foreach ($ids as $id) {
+                    $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
+                    if ($model->getId()) {
+                        $model->setIsRemove(1)->save();
+                    }
+                }
+                $this->messageManager->addSuccess(__('Total of %1 record(s) have been removed.', count($ids)));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __("We couldn't remove the messages because of an error."));
+            }
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Remove.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Remove.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddf9fd3bc8d944bf84fe8cdb10b3bb034bfa0862
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Notification/Remove.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Notification;
+
+class Remove extends \Magento\AdminNotification\Controller\Adminhtml\Notification
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($id = $this->getRequest()->getParam('id')) {
+            $model = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox')->load($id);
+
+            if (!$model->getId()) {
+                $this->_redirect('adminhtml/*/');
+                return;
+            }
+
+            try {
+                $model->setIsRemove(1)->save();
+                $this->messageManager->addSuccess(__('The message has been removed.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __("We couldn't remove the messages because of an error."));
+            }
+
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php
index e41fb155f05627bb03d76c8723e88736a2d62aea..e7650a90e5a9e681c71765ee356a68528330bf85 100644
--- a/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey.php
@@ -30,18 +30,6 @@ namespace Magento\AdminNotification\Controller\Adminhtml;
  */
 class Survey extends \Magento\Backend\App\Action
 {
-    /**
-     * Index Action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        if ($this->getRequest()->getParam('isAjax', false)) {
-            $this->_objectManager->get('Magento\AdminNotification\Model\Survey')->saveSurveyViewed(true);
-        }
-        $this->getResponse()->representJson(\Zend_Json::encode(array('survey_decision_saved' => 1)));
-    }
 
     /**
      * Check if user has enough privileges
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey/Index.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..98caa51c392c17738c03ff4ea315a0fe6b6fcc41
--- /dev/null
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/Survey/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\AdminNotification\Controller\Adminhtml\Survey;
+
+class Index extends \Magento\AdminNotification\Controller\Adminhtml\Survey
+{
+    /**
+     * Index Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('isAjax', false)) {
+            $this->_objectManager->get('Magento\AdminNotification\Model\Survey')->saveSurveyViewed(true);
+        }
+        $this->getResponse()->representJson(\Zend_Json::encode(array('survey_decision_saved' => 1)));
+    }
+}
diff --git a/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php b/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message/ListAction.php
similarity index 80%
rename from app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php
rename to app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message/ListAction.php
index d32a72c10614767d66a2c145af14143ece17cd9c..8fe675076d12981e210d3e927bc5729c77d86d9d 100644
--- a/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message.php
+++ b/app/code/Magento/AdminNotification/Controller/Adminhtml/System/Message/ListAction.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -17,18 +18,18 @@
  * Do not edit or add to this file if you wish to upgrade Magento to newer
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
- * 
- * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license   http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\AdminNotification\Controller\Adminhtml\System;
+namespace Magento\AdminNotification\Controller\Adminhtml\System\Message;
 
-class Message extends \Magento\Backend\App\AbstractAction
+class ListAction extends \Magento\Backend\App\AbstractAction
 {
     /**
      * @return void
      */
-    public function listAction()
+    public function execute()
     {
         $severity = $this->getRequest()->getParam('severity');
         $messageCollection = $this->_objectManager->get(
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php
new file mode 100644
index 0000000000000000000000000000000000000000..a21531748440e66329b0587f9f2268416dc74f17
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class AddConfigured extends \Magento\Sales\Controller\Adminhtml\Order\Create\AddConfigured
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e21b36d93793c368e2591b82b046700fc5b08b7
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order\Create\Cancel
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php
new file mode 100644
index 0000000000000000000000000000000000000000..c561bc9130343288b0f78a55a2e8f6af940d1ddc
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ConfigureProductToAdd extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureProductToAdd
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php
new file mode 100644
index 0000000000000000000000000000000000000000..32b84cdda70332edd6c052647df131c0a7f55e36
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ConfigureQuoteItems extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureQuoteItems
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ab30704cc828bc1f5e88e5a1dcaf2ef9e5947e3
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create\Index
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..380d34378d15aa270aefcfe5dc66a167a042bc7d
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class LoadBlock extends \Magento\Sales\Controller\Adminhtml\Order\Create\LoadBlock
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php
similarity index 51%
rename from app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php
rename to app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php
index c8d74de1e48406c4344b91c4d288dd5675bfad88..fb7d19c26612dbafa0b504a3e9482c66e0852d67 100644
--- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Adminhtml DirectPost Payment Controller
  *
  * Magento
  *
@@ -23,67 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost;
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
 
-class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class Place extends \Magento\Sales\Controller\Adminhtml\Order\Create
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Catalog\Helper\Product $productHelper
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Catalog\Helper\Product $productHelper,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context, $productHelper);
-    }
-
-    /**
-     * Get session model
-     *
-     * @return \Magento\Authorizenet\Model\Directpost\Session
-     */
-    protected function _getDirectPostSession()
-    {
-        return $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
-    }
-
-    /**
-     * Retrieve session object
-     *
-     * @return \Magento\Backend\Model\Session\Quote
-     */
-    protected function _getOrderSession()
-    {
-        return $this->_objectManager->get('Magento\Backend\Model\Session\Quote');
-    }
-
-    /**
-     * Retrieve order create model
-     *
-     * @return \Magento\Sales\Model\AdminOrder\Create
-     */
-    protected function _getOrderCreateModel()
-    {
-        return $this->_objectManager->get('Magento\Sales\Model\AdminOrder\Create');
-    }
-
     /**
      * Send request to authorize.net
      *
      * @return void
      */
-    public function placeAction()
+    public function execute()
     {
         $paymentParam = $this->getRequest()->getParam('payment');
         $controller = $this->getRequest()->getParam('controller');
@@ -130,7 +78,7 @@ class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create
                 )->getCode()
                 ) {
                     //return json with data.
-                    $session = $this->_getDirectPostSession();
+                    $session = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
                     $session->addCheckoutOrderIncrementId($order->getIncrementId());
                     $session->setLastOrderIncrementId($order->getIncrementId());
 
@@ -170,6 +118,7 @@ class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create
                     'sales/order_create/'
                 );
             }
+
             $this->getResponse()->representJson(
                 $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
             );
@@ -180,91 +129,4 @@ class Payment extends \Magento\Sales\Controller\Adminhtml\Order\Create
             );
         }
     }
-
-    /**
-     * Retrieve params and put javascript into iframe
-     *
-     * @return void
-     */
-    public function redirectAction()
-    {
-        $redirectParams = $this->getRequest()->getParams();
-        $params = array();
-        if (!empty($redirectParams['success']) && isset(
-            $redirectParams['x_invoice_num']
-        ) && isset(
-            $redirectParams['controller_action_name']
-        )
-        ) {
-            $params['redirect_parent'] = $this->_objectManager->get(
-                'Magento\Authorizenet\Helper\HelperInterface'
-            )->getSuccessOrderUrl(
-                $redirectParams
-            );
-            $this->_getDirectPostSession()->unsetData('quote_id');
-            //cancel old order
-            $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder();
-            if ($oldOrder->getId()) {
-                /* @var $order \Magento\Sales\Model\Order */
-                $order = $this->_objectManager->create(
-                    'Magento\Sales\Model\Order'
-                )->loadByIncrementId(
-                    $redirectParams['x_invoice_num']
-                );
-                if ($order->getId()) {
-                    $oldOrder->cancel()->save();
-                    $order->save();
-                    $this->_getOrderCreateModel()->getSession()->unsOrderId();
-                }
-            }
-            //clear sessions
-            $this->_getSession()->clearStorage();
-            $this->_getDirectPostSession()->removeCheckoutOrderIncrementId($redirectParams['x_invoice_num']);
-            $this->_objectManager->get('Magento\Backend\Model\Session')->clearStorage();
-            $this->messageManager->addSuccess(__('You created the order.'));
-        }
-
-        if (!empty($redirectParams['error_msg'])) {
-            $cancelOrder = empty($redirectParams['x_invoice_num']);
-            $this->_returnQuote($cancelOrder, $redirectParams['error_msg']);
-        }
-
-        $this->_coreRegistry->register('authorizenet_directpost_form_params', array_merge($params, $redirectParams));
-        $this->_view->loadLayout(false)->renderLayout();
-    }
-
-    /**
-     * Return order quote by ajax
-     *
-     * @return void
-     */
-    public function returnQuoteAction()
-    {
-        $this->_returnQuote();
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1))
-        );
-    }
-
-    /**
-     * Return quote
-     *
-     * @param bool $cancelOrder
-     * @param string $errorMsg
-     * @return void
-     */
-    protected function _returnQuote($cancelOrder = false, $errorMsg = '')
-    {
-        $incrementId = $this->_getDirectPostSession()->getLastOrderIncrementId();
-        if ($incrementId && $this->_getDirectPostSession()->isCheckoutOrderIncrementIdExist($incrementId)) {
-            /* @var $order \Magento\Sales\Model\Order */
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
-            if ($order->getId()) {
-                $this->_getDirectPostSession()->removeCheckoutOrderIncrementId($order->getIncrementId());
-                if ($cancelOrder && $order->getState() == \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT) {
-                    $order->registerCancellation($errorMsg)->save();
-                }
-            }
-        }
-    }
 }
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php
new file mode 100644
index 0000000000000000000000000000000000000000..9299674d3f200b43a23c007f7440a854afafc559
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ProcessData extends \Magento\Sales\Controller\Adminhtml\Order\Create\ProcessData
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..0326491816497eacb4037b105be6b2560b93c21c
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Redirect extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Catalog\Helper\Product $productHelper
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Catalog\Helper\Product $productHelper,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context, $productHelper);
+    }
+
+    /**
+     * Return quote
+     *
+     * @param bool $cancelOrder
+     * @param string $errorMsg
+     * @return void
+     */
+    protected function _returnQuote($cancelOrder, $errorMsg)
+    {
+        $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+        $incrementId = $directpostSession->getLastOrderIncrementId();
+        if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
+            if ($order->getId()) {
+                $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId());
+                if ($cancelOrder && $order->getState() == \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT) {
+                    $order->registerCancellation($errorMsg)->save();
+                }
+            }
+        }
+    }
+
+    /**
+     * Retrieve params and put javascript into iframe
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $redirectParams = $this->getRequest()->getParams();
+        $params = array();
+        if (!empty($redirectParams['success']) && isset(
+            $redirectParams['x_invoice_num']
+        ) && isset(
+            $redirectParams['controller_action_name']
+        )
+        ) {
+            $params['redirect_parent'] = $this->_objectManager->get(
+                'Magento\Authorizenet\Helper\HelperInterface'
+            )->getSuccessOrderUrl(
+                $redirectParams
+            );
+            $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+            $directpostSession->unsetData('quote_id');
+            //cancel old order
+            $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder();
+            if ($oldOrder->getId()) {
+                /* @var $order \Magento\Sales\Model\Order */
+                $order = $this->_objectManager->create(
+                    'Magento\Sales\Model\Order'
+                )->loadByIncrementId(
+                    $redirectParams['x_invoice_num']
+                );
+                if ($order->getId()) {
+                    $oldOrder->cancel()->save();
+                    $order->save();
+                    $this->_getOrderCreateModel()->getSession()->unsOrderId();
+                }
+            }
+            //clear sessions
+            $this->_getSession()->clearStorage();
+            $directpostSession->removeCheckoutOrderIncrementId($redirectParams['x_invoice_num']);
+            $this->_objectManager->get('Magento\Backend\Model\Session')->clearStorage();
+            $this->messageManager->addSuccess(__('You created the order.'));
+        }
+
+        if (!empty($redirectParams['error_msg'])) {
+            $cancelOrder = empty($redirectParams['x_invoice_num']);
+            $this->_returnQuote($cancelOrder, $redirectParams['error_msg']);
+        }
+
+        $this->_coreRegistry->register('authorizenet_directpost_form_params', array_merge($params, $redirectParams));
+        $this->_view->loadLayout(false)->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..6479aac4cff65b4bf9e3f24539ab57d3bce52965
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Reorder extends \Magento\Sales\Controller\Adminhtml\Order\Create\Reorder
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php
new file mode 100644
index 0000000000000000000000000000000000000000..65dc10ee7390937865cf628b9bba576ed817dc54
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ReturnQuote extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Return quote
+     *
+     * @return void
+     */
+    protected function _returnQuote()
+    {
+        $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+        $incrementId = $directpostSession->getLastOrderIncrementId();
+        if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
+            if ($order->getId()) {
+                $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId());
+            }
+        }
+    }
+
+    /**
+     * Return order quote by ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_returnQuote();
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1))
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f74c195ff9b2c1f0fb7db4728d1d021f43b69bc
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create\Save
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..e790ab67e11882e2ace1558f1bc469c5764dbfa3
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create\ShowUpdateResult
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3f9cdb3aa735091c19a0719b15a0ac5e7a73088
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
similarity index 94%
rename from app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php
rename to app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
index 2ce624c8dfc63a66c0818baa6c26720e969f0b1d..711b619cb51ce1d5dc277ddec46e565440f8606d 100644
--- a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Payment/Cancel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet;
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Payment;
 
-/**
- * Authorize Payment Controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Payment extends \Magento\Backend\App\Action
+class Cancel extends \Magento\Backend\App\Action
 {
     /**
      * Session quote
@@ -54,7 +50,7 @@ class Payment extends \Magento\Backend\App\Action
      *
      * @return void
      */
-    public function cancelAction()
+    public function execute()
     {
         $result['success'] = false;
         try {
diff --git a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
similarity index 89%
rename from app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php
rename to app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
index 708d048c5bd14593accfa37206c61bad6379229e..14f717baf764e20f859342690d36c869cb64f85b 100644
--- a/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Authorizenet/Payment/Cancel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Authorizenet\Controller\Authorizenet;
+namespace Magento\Authorizenet\Controller\Authorizenet\Payment;
 
-class Payment extends \Magento\Framework\App\Action\Action
+class Cancel extends \Magento\Framework\App\Action\Action
 {
     /**
      * Checkout session
@@ -36,8 +37,10 @@ class Payment extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Checkout\Model\Session $session
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Checkout\Model\Session $session)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Checkout\Model\Session $session
+    ) {
         $this->_session = $session;
         parent::__construct($context);
     }
@@ -47,7 +50,7 @@ class Payment extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function cancelAction()
+    public function execute()
     {
         $result['success'] = false;
         try {
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
index 0f1916b3c51653993bf029ecc30523f4a97e72f3..c622ef79399629f06c103824a65e7174a5bd3b74 100644
--- a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
@@ -41,19 +41,14 @@ class Payment extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
         $this->_coreRegistry = $coreRegistry;
         parent::__construct($context);
     }
 
-    /**
-     * @return \Magento\Checkout\Model\Session
-     */
-    protected function _getCheckout()
-    {
-        return $this->_objectManager->get('Magento\Checkout\Model\Session');
-    }
 
     /**
      * Get session model
@@ -65,28 +60,6 @@ class Payment extends \Magento\Framework\App\Action\Action
         return $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
     }
 
-    /**
-     * Response action.
-     * Action for Authorize.net SIM Relay Request.
-     *
-     * @return void
-     */
-    public function backendResponseAction()
-    {
-        $this->_responseAction($this->_objectManager->get('Magento\Authorizenet\Helper\Backend'));
-    }
-
-    /**
-     * Response action.
-     * Action for Authorize.net SIM Relay Request.
-     *
-     * @return void
-     */
-    public function responseAction()
-    {
-        $this->_responseAction($this->_objectManager->get('Magento\Authorizenet\Helper\Data'));
-    }
-
     /**
      * Response action.
      * Action for Authorize.net SIM Relay Request.
@@ -140,92 +113,6 @@ class Payment extends \Magento\Framework\App\Action\Action
         $this->_view->loadLayout(false)->renderLayout();
     }
 
-    /**
-     * Retrieve params and put javascript into iframe
-     *
-     * @return void
-     */
-    public function redirectAction()
-    {
-        $redirectParams = $this->getRequest()->getParams();
-        $params = array();
-        if (!empty($redirectParams['success']) && isset(
-            $redirectParams['x_invoice_num']
-        ) && isset(
-            $redirectParams['controller_action_name']
-        )
-        ) {
-            $this->_getDirectPostSession()->unsetData('quote_id');
-            $params['redirect_parent'] = $this->_objectManager->get(
-                'Magento\Authorizenet\Helper\HelperInterface'
-            )->getSuccessOrderUrl(
-                $redirectParams
-            );
-        }
-        if (!empty($redirectParams['error_msg'])) {
-            $cancelOrder = empty($redirectParams['x_invoice_num']);
-            $this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']);
-        }
-
-        if (isset(
-            $redirectParams['controller_action_name']
-        ) && strpos(
-            $redirectParams['controller_action_name'],
-            'sales_order_'
-        ) !== false
-        ) {
-            unset($redirectParams['controller_action_name']);
-            unset($params['redirect_parent']);
-        }
-
-        $this->_coreRegistry->register('authorizenet_directpost_form_params', array_merge($params, $redirectParams));
-        $this->_view->addPageLayoutHandles();
-        $this->_view->loadLayout(false)->renderLayout();
-    }
-
-    /**
-     * Send request to authorize.net
-     *
-     * @return void
-     */
-    public function placeAction()
-    {
-        $paymentParam = $this->getRequest()->getParam('payment');
-        $controller = $this->getRequest()->getParam('controller');
-        if (isset($paymentParam['method'])) {
-            $params = $this->_objectManager->get(
-                'Magento\Authorizenet\Helper\Data'
-            )->getSaveOrderUrlParams(
-                $controller
-            );
-            $this->_getDirectPostSession()->setQuoteId($this->_getCheckout()->getQuote()->getId());
-            $this->_forward(
-                $params['action'],
-                $params['controller'],
-                $params['module'],
-                $this->getRequest()->getParams()
-            );
-        } else {
-            $result = array('error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment');
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Return customer quote by ajax
-     *
-     * @return void
-     */
-    public function returnQuoteAction()
-    {
-        $this->_returnCustomerQuote();
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1))
-        );
-    }
-
     /**
      * Return customer quote
      *
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..07cd435a497dccb4d2d203be9c103e539a4545e4
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class BackendResponse extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Response action.
+     * Action for Authorize.net SIM Relay Request.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_responseAction($this->_objectManager->get('Magento\Authorizenet\Helper\Backend'));
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php
new file mode 100644
index 0000000000000000000000000000000000000000..c84d04019b706a58d8d8a8363bff0b0e80e115b3
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class Place extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * @return \Magento\Checkout\Model\Session
+     */
+    protected function _getCheckout()
+    {
+        return $this->_objectManager->get('Magento\Checkout\Model\Session');
+    }
+    /**
+     * Send request to authorize.net
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $paymentParam = $this->getRequest()->getParam('payment');
+        $controller = $this->getRequest()->getParam('controller');
+        if (isset($paymentParam['method'])) {
+            $params = $this->_objectManager->get(
+                'Magento\Authorizenet\Helper\Data'
+            )->getSaveOrderUrlParams(
+                $controller
+            );
+            $this->_getDirectPostSession()->setQuoteId($this->_getCheckout()->getQuote()->getId());
+            $this->_forward(
+                $params['action'],
+                $params['controller'],
+                $params['module'],
+                $this->getRequest()->getParams()
+            );
+        } else {
+            $result = array('error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment');
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..91238801ef7ecd8dec6890b34742272f7ea91c92
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class Redirect extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Retrieve params and put javascript into iframe
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $redirectParams = $this->getRequest()->getParams();
+        $params = array();
+        if (!empty($redirectParams['success']) && isset(
+            $redirectParams['x_invoice_num']
+        ) && isset(
+            $redirectParams['controller_action_name']
+        )
+        ) {
+            $this->_getDirectPostSession()->unsetData('quote_id');
+            $params['redirect_parent'] = $this->_objectManager->get(
+                'Magento\Authorizenet\Helper\HelperInterface'
+            )->getSuccessOrderUrl(
+                $redirectParams
+            );
+        }
+        if (!empty($redirectParams['error_msg'])) {
+            $cancelOrder = empty($redirectParams['x_invoice_num']);
+            $this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']);
+        }
+
+        if (isset(
+            $redirectParams['controller_action_name']
+        ) && strpos(
+            $redirectParams['controller_action_name'],
+            'sales_order_'
+        ) !== false
+        ) {
+            unset($redirectParams['controller_action_name']);
+            unset($params['redirect_parent']);
+        }
+
+        $this->_coreRegistry->register('authorizenet_directpost_form_params', array_merge($params, $redirectParams));
+        $this->_view->addPageLayoutHandles();
+        $this->_view->loadLayout(false)->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3a2237d817127b8c314f51605f35bcdd3a1deb6
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class Response extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Response action.
+     * Action for Authorize.net SIM Relay Request.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_responseAction($this->_objectManager->get('Magento\Authorizenet\Helper\Data'));
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e988cc4fe3b552cad4950cd081858805ad14640
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class ReturnQuote extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Return customer quote by ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_returnCustomerQuote();
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array('success' => 1))
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/App/AbstractAction.php b/app/code/Magento/Backend/App/AbstractAction.php
index 9d533f7018a669afd39d18cea34b05a695c90385..381771d00cf7c40e9a43f9e965a1dfd768f3f424 100644
--- a/app/code/Magento/Backend/App/AbstractAction.php
+++ b/app/code/Magento/Backend/App/AbstractAction.php
@@ -227,7 +227,14 @@ abstract class AbstractAction extends \Magento\Framework\App\Action\Action
         }
 
         if ($request->isDispatched() && $request->getActionName() !== 'denied' && !$this->_isAllowed()) {
-            $this->_forward('denied');
+            $this->_response->setHeader('HTTP/1.1', '403 Forbidden');
+            $this->_response->setHttpResponseCode(403);
+            if (!$this->_auth->isLoggedIn()) {
+                return $this->_redirect('*/auth/login');
+            }
+            $this->_view->loadLayout(array('default', 'adminhtml_denied'), true, true, false);
+            $this->_view->renderLayout();
+            $this->_request->setDispatched(true);
             return $this->_response;
         }
 
@@ -315,35 +322,6 @@ abstract class AbstractAction extends \Magento\Framework\App\Action\Action
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function deniedAction()
-    {
-        $this->getResponse()->setHeader('HTTP/1.1', '403 Forbidden');
-        if (!$this->_auth->isLoggedIn()) {
-            $this->_redirect('*/auth/login');
-            return;
-        }
-        $this->_view->loadLayout(array('default', 'adminhtml_denied'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * No route action
-     *
-     * @param null $coreRoute
-     * @return void
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function norouteAction($coreRoute = null)
-    {
-        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
-        $this->getResponse()->setHeader('Status', '404 File not found');
-        $this->_view->loadLayout(array('default', 'adminhtml_noroute'));
-        $this->_view->renderLayout();
-    }
-
     /**
      * Set redirect into response
      *
diff --git a/app/code/Magento/Backend/App/Router/DefaultRouter.php b/app/code/Magento/Backend/App/Router.php
similarity index 85%
rename from app/code/Magento/Backend/App/Router/DefaultRouter.php
rename to app/code/Magento/Backend/App/Router.php
index c4be5bccb3bc0d5ef5d5b7c0f4ffb98753326e80..23f19e5c6733497ab9506de934cbee87a592bf44 100644
--- a/app/code/Magento/Backend/App/Router/DefaultRouter.php
+++ b/app/code/Magento/Backend/App/Router.php
@@ -24,9 +24,9 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  *
  */
-namespace Magento\Backend\App\Router;
+namespace Magento\Backend\App;
 
-class DefaultRouter extends \Magento\Core\App\Router\Base
+class Router extends \Magento\Core\App\Router\Base
 {
     /**
      * @var \Magento\Backend\App\ConfigInterface
@@ -34,7 +34,7 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
     protected $_backendConfig;
 
     /**
-     * @var \Magento\Core\Model\Url|\Magento\Framework\UrlInterface $url
+     * @var \Magento\Framework\UrlInterface $url
      */
     protected $_url;
 
@@ -49,9 +49,23 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
      *
      * @var string[]
      */
-    protected $_requiredParams = array('areaFrontName', 'moduleFrontName', 'controllerName', 'actionName');
+    protected $_requiredParams = array('areaFrontName', 'moduleFrontName', 'actionPath', 'actionName');
 
     /**
+     * We need to have noroute action in this router
+     * not to pass dispatching to next routers
+     *
+     * @var bool
+     */
+    protected $applyNoRoute = true;
+
+    /**
+     * @var string
+     */
+    protected $pathPrefix = \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE;
+
+    /**
+     * @param \Magento\Framework\App\Router\ActionList $actionList
      * @param \Magento\Framework\App\ActionFactory $actionFactory
      * @param \Magento\Framework\App\DefaultPathInterface $defaultPath
      * @param \Magento\Framework\App\ResponseFactory $responseFactory
@@ -69,6 +83,7 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
+        \Magento\Framework\App\Router\ActionList $actionList,
         \Magento\Framework\App\ActionFactory $actionFactory,
         \Magento\Framework\App\DefaultPathInterface $defaultPath,
         \Magento\Framework\App\ResponseFactory $responseFactory,
@@ -84,6 +99,7 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
         \Magento\Backend\App\ConfigInterface $backendConfig
     ) {
         parent::__construct(
+            $actionList,
             $actionFactory,
             $defaultPath,
             $responseFactory,
@@ -110,17 +126,6 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
         return (string)$this->_backendConfig->getValue('web/default/admin');
     }
 
-    /**
-     * We need to have noroute action in this router
-     * not to pass dispatching to next routers
-     *
-     * @return bool
-     */
-    protected function _noRouteShouldBeApplied()
-    {
-        return true;
-    }
-
     /**
      * Check whether URL for corresponding path should use https protocol
      *
@@ -163,22 +168,4 @@ class DefaultRouter extends \Magento\Core\App\Router\Base
     {
         return false;
     }
-
-    /**
-     * Build controller class name based on moduleName and controllerName
-     *
-     * @param string $module
-     * @param string $controller
-     * @return string
-     */
-    public function getControllerClassName($module, $controller)
-    {
-        $parts = explode('_', $module);
-        $parts = array_splice($parts, 0, 2);
-        $parts[] = 'Controller';
-        $parts[] = \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE;
-        $parts[] = $controller;
-
-        return $this->nameBuilder->buildClassName($parts);
-    }
 }
diff --git a/app/code/Magento/Backend/App/Router/NoRouteHandler.php b/app/code/Magento/Backend/App/Router/NoRouteHandler.php
index 5146e9931134c7dec22403be1f54658086078661..4f8909eb0ad9a37deedec773526ddaa974997b17 100644
--- a/app/code/Magento/Backend/App/Router/NoRouteHandler.php
+++ b/app/code/Magento/Backend/App/Router/NoRouteHandler.php
@@ -30,12 +30,12 @@ class NoRouteHandler implements \Magento\Framework\App\Router\NoRouteHandlerInte
     /**
      * @var \Magento\Backend\Helper\Data
      */
-    protected $_helper;
+    protected $helper;
 
     /**
      * @var \Magento\Framework\App\Route\ConfigInterface
      */
-    protected $_routeConfig;
+    protected $routeConfig;
 
     /**
      * @param \Magento\Backend\Helper\Data $helper
@@ -45,8 +45,8 @@ class NoRouteHandler implements \Magento\Framework\App\Router\NoRouteHandlerInte
         \Magento\Backend\Helper\Data $helper,
         \Magento\Framework\App\Route\ConfigInterface $routeConfig
     ) {
-        $this->_helper = $helper;
-        $this->_routeConfig = $routeConfig;
+        $this->helper = $helper;
+        $this->routeConfig = $routeConfig;
     }
 
     /**
@@ -60,17 +60,14 @@ class NoRouteHandler implements \Magento\Framework\App\Router\NoRouteHandlerInte
         $requestPathParams = explode('/', trim($request->getPathInfo(), '/'));
         $areaFrontName = array_shift($requestPathParams);
 
-        if ($areaFrontName == $this->_helper->getAreaFrontName()) {
+        if ($areaFrontName == $this->helper->getAreaFrontName()) {
 
-            $moduleName = $this->_routeConfig->getRouteFrontName('adminhtml');
-            $controllerName = 'noroute';
+            $moduleName = $this->routeConfig->getRouteFrontName('adminhtml');
+            $actionNamespace = 'noroute';
             $actionName = 'index';
-
-            $request->setModuleName($moduleName)->setControllerName($controllerName)->setActionName($actionName);
-
+            $request->setModuleName($moduleName)->setControllerName($actionNamespace)->setActionName($actionName);
             return true;
         }
-
         return false;
     }
 }
diff --git a/app/code/Magento/Backend/Block/Cache.php b/app/code/Magento/Backend/Block/Cache.php
index fc99635e29d43d91fafeaf496ce218896b678b45..4d80b58bd048c9b80788588d19e33b2748eef800 100644
--- a/app/code/Magento/Backend/Block/Cache.php
+++ b/app/code/Magento/Backend/Block/Cache.php
@@ -35,8 +35,8 @@ class Cache extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'cache';
         $this->_headerText = __('Cache Storage Management');
         parent::_construct();
-        $this->_removeButton('add');
-        $this->_addButton(
+        $this->buttonList->remove('add');
+        $this->buttonList->add(
             'flush_magento',
             array(
                 'label' => __('Flush Magento Cache'),
@@ -46,7 +46,7 @@ class Cache extends \Magento\Backend\Block\Widget\Grid\Container
         );
 
         $message = __('Cache storage may contain additional data. Are you sure that you want flush it?');
-        $this->_addButton(
+        $this->buttonList->add(
             'flush_system',
             array(
                 'label' => __('Flush Cache Storage'),
diff --git a/app/code/Magento/Backend/Block/System/Account/Edit.php b/app/code/Magento/Backend/Block/System/Account/Edit.php
index b1a790c923934d3dd5f3e397bd9c1a5940b4e700..73caffabf1ab0263365e24370c5395b9a07cf5d2 100644
--- a/app/code/Magento/Backend/Block/System/Account/Edit.php
+++ b/app/code/Magento/Backend/Block/System/Account/Edit.php
@@ -39,9 +39,9 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         $this->_blockGroup = 'Magento_Backend';
         $this->_controller = 'system_account';
-        $this->_updateButton('save', 'label', __('Save Account'));
-        $this->_removeButton('delete');
-        $this->_removeButton('back');
+        $this->buttonList->update('save', 'label', __('Save Account'));
+        $this->buttonList->remove('delete');
+        $this->buttonList->remove('back');
     }
 
     /**
diff --git a/app/code/Magento/Backend/Block/System/Config/Edit.php b/app/code/Magento/Backend/Block/System/Config/Edit.php
index 762372f696d34ed3f5125a86eb9ba945ca9af536..0f41408e0b8b654ab03fc22c10acd1992800247c 100644
--- a/app/code/Magento/Backend/Block/System/Config/Edit.php
+++ b/app/code/Magento/Backend/Block/System/Config/Edit.php
@@ -121,6 +121,6 @@ class Edit extends \Magento\Backend\Block\Widget
      */
     public function getSaveUrl()
     {
-        return $this->getUrl('*/system_config_save/index', array('_current' => true));
+        return $this->getUrl('*/system_config/save', array('_current' => true));
     }
 }
diff --git a/app/code/Magento/Backend/Block/System/Store/Delete.php b/app/code/Magento/Backend/Block/System/Store/Delete.php
index 39730fc9661de6f28091f53cb6df0a670eaeb525..6a4fe5804b7933f67001ca2d70a6550b906ec65f 100644
--- a/app/code/Magento/Backend/Block/System/Store/Delete.php
+++ b/app/code/Magento/Backend/Block/System/Store/Delete.php
@@ -44,18 +44,18 @@ class Delete extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('save');
-        $this->_removeButton('reset');
+        $this->buttonList->remove('save');
+        $this->buttonList->remove('reset');
 
-        $this->_updateButton('delete', 'region', 'footer');
-        $this->_updateButton('delete', 'onclick', null);
-        $this->_updateButton(
+        $this->buttonList->update('delete', 'region', 'footer');
+        $this->buttonList->update('delete', 'onclick', null);
+        $this->buttonList->update(
             'delete',
             'data_attribute',
             array('mage-init' => array('button' => array('event' => 'save', 'target' => '#edit_form')))
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'cancel',
             array('label' => __('Cancel'), 'onclick' => 'setLocation(\'' . $this->getBackUrl() . '\')'),
             2,
@@ -86,7 +86,7 @@ class Delete extends \Magento\Backend\Block\Widget\Form\Container
      */
     public function setStoreTypeTitle($title)
     {
-        $this->_updateButton('delete', 'label', __('Delete %1', $title));
+        $this->buttonList->update('delete', 'label', __('Delete %1', $title));
         return $this->setData('store_type_title', $title);
     }
 
@@ -99,8 +99,8 @@ class Delete extends \Magento\Backend\Block\Widget\Form\Container
     public function setBackUrl($url)
     {
         $this->setData('back_url', $url);
-        $this->_updateButton('cancel', 'onclick', "setLocation('" . $url . "')");
-        $this->_updateButton('back', 'onclick', "setLocation('" . $url . "')");
+        $this->buttonList->update('cancel', 'onclick', "setLocation('" . $url . "')");
+        $this->buttonList->update('back', 'onclick', "setLocation('" . $url . "')");
         return $this;
     }
 }
diff --git a/app/code/Magento/Backend/Block/System/Store/Edit.php b/app/code/Magento/Backend/Block/System/Store/Edit.php
index d37f29860d93cf4b96cd8f50d611f8473fe8a9ac..9b9c6617c98f409bb69f91f4b867e2a4c0b52658 100644
--- a/app/code/Magento/Backend/Block/System/Store/Edit.php
+++ b/app/code/Magento/Backend/Block/System/Store/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -94,19 +94,20 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', $saveLabel);
-        $this->_updateButton('delete', 'label', $deleteLabel);
-        $this->_updateButton('delete', 'onclick', 'setLocation(\'' . $deleteUrl . '\');');
+        $this->buttonList->update('save', 'label', $saveLabel);
+        $this->buttonList->update('delete', 'label', $deleteLabel);
+        $this->buttonList->update('delete', 'onclick', 'setLocation(\'' . $deleteUrl . '\');');
 
         if (!$this->_coreRegistry->registry('store_data')) {
             return;
         }
 
         if (!$this->_coreRegistry->registry('store_data')->isCanDelete()) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
         if ($this->_coreRegistry->registry('store_data')->isReadOnly()) {
-            $this->_removeButton('save')->_removeButton('reset');
+            $this->buttonList->remove('save');
+            $this->buttonList->remove('reset');
         }
     }
 
diff --git a/app/code/Magento/Backend/Block/System/Store/Store.php b/app/code/Magento/Backend/Block/System/Store/Store.php
index 0b438b0c373f6a256138aeb3dbc115ee9c3c1865..b2484bf212a565618f6ce1354ea2fa56a4f846a2 100644
--- a/app/code/Magento/Backend/Block/System/Store/Store.php
+++ b/app/code/Magento/Backend/Block/System/Store/Store.php
@@ -44,19 +44,13 @@ class Store extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'system_store';
         $this->_headerText = __('Stores');
         parent::_construct();
-    }
 
-    /**
-     * {@inheritdoc}
-     */
-    protected function _prepareLayout()
-    {
         /* Update default add button to add website button */
-        $this->_updateButton('add', 'label', __('Create Website'));
-        $this->_updateButton('add', 'onclick', "setLocation('" . $this->getUrl('adminhtml/*/newWebsite') . "')");
+        $this->buttonList->update('add', 'label', __('Create Website'));
+        $this->buttonList->update('add', 'onclick', "setLocation('" . $this->getUrl('adminhtml/*/newWebsite') . "')");
 
         /* Add Store Group button */
-        $this->_addButton(
+        $this->buttonList->add(
             'add_group',
             array(
                 'label' => __('Create Store'),
@@ -67,7 +61,7 @@ class Store extends \Magento\Backend\Block\Widget\Grid\Container
         );
 
         /* Add Store button */
-        $this->_addButton(
+        $this->buttonList->add(
             'add_store',
             array(
                 'label' => __('Create Store View'),
@@ -75,7 +69,5 @@ class Store extends \Magento\Backend\Block\Widget\Grid\Container
                 'class' => 'add add-store-view'
             )
         );
-
-        return parent::_prepareLayout();
     }
 }
diff --git a/app/code/Magento/Backend/Block/System/Variable.php b/app/code/Magento/Backend/Block/System/Variable.php
index 2221ff5828cdcd7dbd67c64f9ffd22dab5830e48..c7826f73c178d98ba50f4aa3db7009ec7e119edd 100644
--- a/app/code/Magento/Backend/Block/System/Variable.php
+++ b/app/code/Magento/Backend/Block/System/Variable.php
@@ -41,6 +41,6 @@ class Variable extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'system_variable';
         $this->_headerText = __('Custom Variables');
         parent::_construct();
-        $this->_updateButton('add', 'label', __('Add New Variable'));
+        $this->buttonList->update('add', 'label', __('Add New Variable'));
     }
 }
diff --git a/app/code/Magento/Backend/Block/System/Variable/Edit.php b/app/code/Magento/Backend/Block/System/Variable/Edit.php
index dd563d47d2ae0a68bbc0cf54ab52717714835237..87bbe232e72ff7fda5f8e2b20af2e53b75b77b0b 100644
--- a/app/code/Magento/Backend/Block/System/Variable/Edit.php
+++ b/app/code/Magento/Backend/Block/System/Variable/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -81,7 +81,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
      */
     protected function _preparelayout()
     {
-        $this->_addButton(
+        $this->addButton(
             'save_and_edit',
             array(
                 'label' => __('Save and Continue Edit'),
diff --git a/app/code/Magento/Backend/Block/Template/Context.php b/app/code/Magento/Backend/Block/Template/Context.php
index 81adf1abc1ea29f25cc09129a9a46cdb22bb50b5..f28b2f8a0a607dcb31f6ee03e5ff06656106520e 100644
--- a/app/code/Magento/Backend/Block/Template/Context.php
+++ b/app/code/Magento/Backend/Block/Template/Context.php
@@ -1,6 +1,4 @@
 <?php
-namespace Magento\Backend\Block\Template;
-
 /**
  * Backend block template context
  *
@@ -24,7 +22,11 @@ namespace Magento\Backend\Block\Template;
  *
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- *
+ */
+
+namespace Magento\Backend\Block\Template;
+
+/**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Context extends \Magento\Framework\View\Element\Template\Context
diff --git a/app/code/Magento/Backend/Block/Urlrewrite.php b/app/code/Magento/Backend/Block/Urlrewrite.php
index ddaef6b5d17383ae385b3764b6c4f0567fd341b8..d3306b3dab3b8186f98c7c3cdfe179bb6fd3756a 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite.php
+++ b/app/code/Magento/Backend/Block/Urlrewrite.php
@@ -46,12 +46,12 @@ class Urlrewrite extends \Magento\Backend\Block\Widget\Grid\Container
     protected $_urlrewriteSelector;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Backend\Block\Urlrewrite\Selector $urlrewriteSelector
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Backend\Block\Urlrewrite\Selector $urlrewriteSelector,
         array $data = array()
     ) {
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
index 76f7d11b8f24caca91bab770ecfe8ce4f62c3be6..c8ffa03ca60e0caf7311bcdd7435f6f86dfbb42e 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
+++ b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Category/Edit.php
@@ -40,14 +40,14 @@ class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
     protected $_categoryFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Catalog\Model\CategoryFactory $categoryFactory,
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
index 35a665146f579b480a0ba39cc70a5d25a41da9f4..648aa40029cf5db34c2f8a0061066053b631ba51 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
+++ b/app/code/Magento/Backend/Block/Urlrewrite/Catalog/Product/Edit.php
@@ -48,7 +48,7 @@ class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
     protected $_categoryFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
@@ -56,7 +56,7 @@ class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Catalog\Model\ProductFactory $productFactory,
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
index 6174a4561d028738639be08825234d384c18ad8b..ccb5872dac8594b3c1d9deef6aee6784043ef508 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
+++ b/app/code/Magento/Backend/Block/Urlrewrite/Cms/Page/Edit.php
@@ -39,14 +39,14 @@ class Edit extends \Magento\Backend\Block\Urlrewrite\Edit
     protected $_pageFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param \Magento\Cms\Model\PageFactory $pageFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         \Magento\Cms\Model\PageFactory $pageFactory,
diff --git a/app/code/Magento/Backend/Block/Urlrewrite/Edit.php b/app/code/Magento/Backend/Block/Urlrewrite/Edit.php
index bfa2e71dca6a709f6c0c517463fe453029646088..66ae64dbdde81d06682ff2cefc4c81768ef30836 100644
--- a/app/code/Magento/Backend/Block/Urlrewrite/Edit.php
+++ b/app/code/Magento/Backend/Block/Urlrewrite/Edit.php
@@ -65,13 +65,13 @@ class Edit extends \Magento\Backend\Block\Widget\Container
     protected $_rewriteFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory
      * @param \Magento\Backend\Helper\Data $adminhtmlData
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\UrlRewrite\Model\UrlRewriteFactory $rewriteFactory,
         \Magento\Backend\Helper\Data $adminhtmlData,
         array $data = array()
@@ -140,7 +140,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addResetButton()
     {
-        $this->_addButton(
+        $this->buttonList->add(
             'reset',
             array(
                 'label' => __('Reset'),
@@ -158,7 +158,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addBackButton()
     {
-        $this->_addButton(
+        $this->buttonList->add(
             'back',
             array(
                 'label' => __('Back'),
@@ -177,7 +177,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _updateBackButtonLink($link)
     {
-        $this->_updateButton('back', 'onclick', 'setLocation(\'' . $link . '\')');
+        $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $link . '\')');
     }
 
     /**
@@ -187,7 +187,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addDeleteButton()
     {
-        $this->_addButton(
+        $this->buttonList->add(
             'delete',
             array(
                 'label' => __('Delete'),
@@ -210,7 +210,7 @@ class Edit extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addSaveButton()
     {
-        $this->_addButton(
+        $this->buttonList->add(
             'save',
             array(
                 'label' => __('Save'),
diff --git a/app/code/Magento/Backend/Block/Widget/Button/ButtonList.php b/app/code/Magento/Backend/Block/Widget/Button/ButtonList.php
new file mode 100644
index 0000000000000000000000000000000000000000..4375aba3b95a5fd04021e6a14d6827dc8ae530ea
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/ButtonList.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button;
+
+class ButtonList
+{
+    /**
+     * @var ItemFactory
+     */
+    protected $itemFactory;
+
+    /**
+     * @param ItemFactory $itemFactory
+     */
+    public function __construct(ItemFactory $itemFactory)
+    {
+        $this->itemFactory = $itemFactory;
+    }
+
+    /**
+     * @var array
+     */
+    protected $_buttons = [-1 => [], 0 => [], 1 => []];
+
+    /**
+     * Add a button
+     *
+     * @param string $buttonId
+     * @param array $data
+     * @param integer $level
+     * @param integer $sortOrder
+     * @param string|null $region That button should be displayed in ('toolbar', 'header', 'footer', null)
+     * @return void
+     */
+    public function add($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    {
+        if (!isset($this->_buttons[$level])) {
+            $this->_buttons[$level] = array();
+        }
+
+        $data['id'] = empty($data['id']) ? $buttonId : $data['id'];
+        $data['button_key'] = $data['id'] . '_button' ;
+        $data['region'] = empty($data['region']) ? $region : $data['region'];
+        $data['level'] = $level;
+        $sortOrder = $sortOrder ?: (count($this->_buttons[$level]) + 1) * 10;
+        $data['sort_order'] = empty($data['sort_order']) ? $sortOrder : $data['sort_order'];
+        $this->_buttons[$level][$buttonId] = $this->itemFactory->create(['data' => $data]);
+    }
+
+    /**
+     * Remove existing button
+     *
+     * @param string $buttonId
+     * @return void
+     */
+    public function remove($buttonId)
+    {
+        foreach ($this->_buttons as $level => $buttons) {
+            if (isset($buttons[$buttonId])) {
+                /** @var Item $item */
+                $item = $buttons[$buttonId];
+                $item->isDeleted(true);
+                unset($this->_buttons[$level][$buttonId]);
+            }
+        }
+    }
+
+    /**
+     * Update specified button property
+     *
+     * @param string $buttonId
+     * @param string|null $key
+     * @param string $data
+     * @return void
+     */
+    public function update($buttonId, $key, $data)
+    {
+        foreach ($this->_buttons as $level => $buttons) {
+            if (isset($buttons[$buttonId])) {
+                if (!empty($key)) {
+                    if ('level' == $key) {
+                        $this->_buttons[$data][$buttonId] = $this->_buttons[$level][$buttonId];
+                        unset($this->_buttons[$level][$buttonId]);
+                    } else {
+                        /** @var Item $item */
+                        $item = $this->_buttons[$level][$buttonId];
+                        $item->setData($key, $data);
+                    }
+                } else {
+                    /** @var Item $item */
+                    $item = $this->_buttons[$level][$buttonId];
+                    $item->setData($data);
+                }
+                break;
+            }
+        }
+    }
+
+    /**
+     * Get all buttons
+     *
+     * @return array
+     */
+    public function getItems()
+    {
+        array_walk($this->_buttons, function (&$item) {
+            uasort($item, [$this, 'sortButtons']);
+        });
+        return $this->_buttons;
+    }
+
+    /**
+     * Sort buttons by sort order
+     *
+     * @param Item $itemA
+     * @param Item $itemB
+     * @return int
+     */
+    public function sortButtons(Item $itemA, Item $itemB)
+    {
+        $sortOrderA = intval($itemA->getSortOrder());
+        $sortOrderB = intval($itemB->getSortOrder());
+
+        if ($sortOrderA == $sortOrderB) {
+            return 0;
+        }
+        return ($sortOrderA < $sortOrderB) ? -1 : 1;
+    }
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Button/ContextInterface.php b/app/code/Magento/Backend/Block/Widget/Button/ContextInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..45072dd88773b7a694dc6ed63e0e09cb12aaa9b4
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/ContextInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button;
+
+interface ContextInterface
+{
+    /**
+     * Check whether button rendering is allowed in current context
+     *
+     * @param \Magento\Backend\Block\Widget\Button\Item $item
+     * @return bool
+     */
+    public function canRender(\Magento\Backend\Block\Widget\Button\Item $item);
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Button/Item.php b/app/code/Magento/Backend/Block/Widget/Button/Item.php
new file mode 100644
index 0000000000000000000000000000000000000000..04c027fcd1a5c7c8353d9bd217a9ee1273289c9d
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/Item.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button;
+
+/**
+ * @method string getButtonKey
+ * @method string getRegion
+ * @method string getName
+ * @method int getLevel
+ * @method int getSortOrder
+ * @method string getTitle
+ */
+class Item extends \Magento\Framework\Object
+{
+
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Button/Toolbar.php b/app/code/Magento/Backend/Block/Widget/Button/Toolbar.php
new file mode 100644
index 0000000000000000000000000000000000000000..720e2637d355631e8fdb676ef0bd8386298df4f0
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/Toolbar.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button;
+
+class Toolbar implements ToolbarInterface
+{
+    /**
+     * @var \Magento\Framework\View\LayoutInterface
+     */
+    protected $layout;
+
+    /**
+     * @param \Magento\Framework\View\LayoutInterface $layout
+     */
+    public function __construct(\Magento\Framework\View\LayoutInterface $layout)
+    {
+        $this->layout = $layout;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function pushButtons(
+        \Magento\Framework\View\Element\AbstractBlock $context,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+    ) {
+        foreach ($buttonList->getItems() as $buttons) {
+            /** @var \Magento\Backend\Block\Widget\Button\Item $item */
+            foreach ($buttons as $item) {
+                $containerName = $context->getNameInLayout() . '-' . $item->getButtonKey();
+
+                $container = $this->createContainer($containerName, $item);
+
+                if ($item->hasData('name')) {
+                    $item->setData('element_name', $item->getName());
+                }
+
+                if ($container) {
+                    $container->setContext($context);
+                    $toolbar = $this->getToolbar($context, $item->getRegion());
+                    $toolbar->setChild($item->getButtonKey(), $container);
+                }
+            }
+        }
+    }
+
+    /**
+     * Create button container
+     *
+     * @param string $containerName
+     * @param \Magento\Backend\Block\Widget\Button\Item $buttonItem
+     * @return \Magento\Backend\Block\Widget\Button\Toolbar\Container
+     */
+    protected function createContainer($containerName, $buttonItem)
+    {
+        $container = $this->layout->createBlock(
+            '\Magento\Backend\Block\Widget\Button\Toolbar\Container',
+            $containerName,
+            ['data' => ['button_item' => $buttonItem]]
+        );
+        return $container;
+    }
+
+    /**
+     * Return button parent block
+     *
+     * @param \Magento\Framework\View\Element\AbstractBlock $context
+     * @param string $region
+     * @return \Magento\Backend\Block\Template
+     */
+    protected function getToolbar(\Magento\Framework\View\Element\AbstractBlock $context, $region)
+    {
+        $parent = null;
+
+        if (!$region || $region == 'header' || $region == 'footer') {
+            $parent = $context;
+        } elseif ($region == 'toolbar') {
+            $parent = $this->layout->getBlock('page.actions.toolbar');
+        } else {
+            $parent = $this->layout->getBlock($region);
+        }
+
+        if ($parent) {
+            return $parent;
+        }
+        return $context;
+    }
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php b/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6982ca092cd40ebb149708bb8cb33021afc1fa6
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/Toolbar/Container.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button\Toolbar;
+
+use \Magento\Backend\Block\Widget\Button\ContextInterface;
+
+/**
+ * @method \Magento\Backend\Block\Widget\Button\Item getButtonItem
+ * @method ContextInterface getContext
+ * @method ContextInterface setContext(ContextInterface $context)
+ */
+class Container extends \Magento\Framework\View\Element\AbstractBlock
+{
+    /**
+     * Create button renderer
+     *
+     * @param string $blockName
+     * @param string $blockClassName
+     * @return \Magento\Backend\Block\Widget\Button
+     */
+    protected function createButton($blockName, $blockClassName = null)
+    {
+        if (null === $blockClassName) {
+            $blockClassName = 'Magento\Backend\Block\Widget\Button';
+        }
+        return $this->getLayout()->createBlock($blockClassName, $blockName);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _toHtml()
+    {
+        $item = $this->getButtonItem();
+        $context = $this->getContext();
+
+        if ($item && $context && $context->canRender($item)) {
+            $data = $item->getData();
+            $blockClassName = isset($data['class_name']) ? $data['class_name'] : null;
+            $buttonName = $this->getContext()->getNameInLayout() . '-' . $item->getId() . '-button';
+            $block = $this->createButton($buttonName, $blockClassName);
+            $block->setData($data);
+            return $block->toHtml();
+        }
+        return parent::_toHtml();
+    }
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Button/ToolbarInterface.php b/app/code/Magento/Backend/Block/Widget/Button/ToolbarInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..0117008c3bf4ffdb3295691d230c50d2c598c326
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Button/ToolbarInterface.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget\Button;
+
+interface ToolbarInterface
+{
+    /**
+     * Push buttons into toolbar
+     *
+     * @param \Magento\Framework\View\Element\AbstractBlock $context
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @return void
+     */
+    public function pushButtons(
+        \Magento\Framework\View\Element\AbstractBlock $context,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+    );
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Container.php b/app/code/Magento/Backend/Block/Widget/Container.php
index 78c35dab462f2a0fecc4747304e0f96bfb9a528b..f7d2ac6a8134e47474dc75d3ae8e072b63a70ddb 100644
--- a/app/code/Magento/Backend/Block/Widget/Container.php
+++ b/app/code/Magento/Backend/Block/Widget/Container.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Backend container block
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +23,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Backend\Block\Widget;
 
-/**
- * Backend container block
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Container extends \Magento\Backend\Block\Template
+use Magento\Framework\View\Element\Template;
+
+class Container extends \Magento\Backend\Block\Template implements ContainerInterface
 {
     /**#@+
      * Initialization parameters in pseudo-constructor
@@ -46,13 +46,6 @@ class Container extends \Magento\Backend\Block\Template
      */
     protected $_controller = 'empty';
 
-    /**
-     * Array of buttons
-     *
-     * @var array
-     */
-    protected $_buttons = array(-1 => array(), 0 => array(), 1 => array());
-
     /**
      * Header text
      *
@@ -60,6 +53,27 @@ class Container extends \Magento\Backend\Block\Template
      */
     protected $_headerText = 'Container Widget Header';
 
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var Button\ToolbarInterface
+     */
+    protected $toolbar;
+
+    /**
+     * @param Context $context
+     * @param array $data
+     */
+    public function __construct(\Magento\Backend\Block\Widget\Context $context, array $data = array())
+    {
+        $this->buttonList = $context->getButtonList();
+        $this->toolbar = $context->getButtonToolbar();
+        parent::__construct($context, $data);
+    }
+
     /**
      * Initialize "controller" and "header text"
      *
@@ -77,38 +91,7 @@ class Container extends \Magento\Backend\Block\Template
     }
 
     /**
-     * Add a button
-     *
-     * @param string $buttonId
-     * @param array $data
-     * @param integer $level
-     * @param integer $sortOrder
-     * @param string|null $region That button should be displayed in ('toolbar', 'header', 'footer', null)
-     * @return $this
-     */
-    protected function _addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
-    {
-        if (!isset($this->_buttons[$level])) {
-            $this->_buttons[$level] = array();
-        }
-        if (empty($data['id'])) {
-            $data['id'] = $buttonId;
-        }
-        $this->_buttons[$level][$buttonId] = $data;
-        $this->_buttons[$level][$buttonId]['region'] = $region;
-        if (empty($this->_buttons[$level][$buttonId]['id'])) {
-            $this->_buttons[$level][$buttonId]['id'] = $buttonId;
-        }
-        if ($sortOrder) {
-            $this->_buttons[$level][$buttonId]['sort_order'] = $sortOrder;
-        } else {
-            $this->_buttons[$level][$buttonId]['sort_order'] = count($this->_buttons[$level]) * 10;
-        }
-        return $this;
-    }
-
-    /**
-     * Public wrapper for protected _addButton method
+     * Public wrapper for the button list
      *
      * @param string $buttonId
      * @param array $data
@@ -119,64 +102,19 @@ class Container extends \Magento\Backend\Block\Template
      */
     public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
     {
-        return $this->_addButton($buttonId, $data, $level, $sortOrder, $region);
-    }
-
-    /**
-     * Remove existing button
-     *
-     * @param string $buttonId
-     * @return $this
-     */
-    protected function _removeButton($buttonId)
-    {
-        foreach ($this->_buttons as $level => $buttons) {
-            if (isset($buttons[$buttonId])) {
-                unset($this->_buttons[$level][$buttonId]);
-            }
-        }
+        $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
         return $this;
     }
 
     /**
-     * Public wrapper for the _removeButton() method
+     * Public wrapper for the button list
      *
      * @param string $buttonId
      * @return $this
      */
     public function removeButton($buttonId)
     {
-        return $this->_removeButton($buttonId);
-    }
-
-    /**
-     * Update specified button property
-     *
-     * @param string $buttonId
-     * @param string|null $key
-     * @param string $data
-     * @return $this
-     */
-    protected function _updateButton($buttonId, $key, $data)
-    {
-        foreach ($this->_buttons as $level => $buttons) {
-            if (isset($buttons[$buttonId])) {
-                if (!empty($key)) {
-                    if ($child = $this->getChildBlock($buttonId . '_button')) {
-                        $child->setData($key, $data);
-                    }
-                    if ('level' == $key) {
-                        $this->_buttons[$data][$buttonId] = $this->_buttons[$level][$buttonId];
-                        unset($this->_buttons[$level][$buttonId]);
-                    } else {
-                        $this->_buttons[$level][$buttonId][$key] = $data;
-                    }
-                } else {
-                    $this->_buttons[$level][$buttonId] = $data;
-                }
-                break;
-            }
-        }
+        $this->buttonList->remove($buttonId);
         return $this;
     }
 
@@ -190,7 +128,8 @@ class Container extends \Magento\Backend\Block\Template
      */
     public function updateButton($buttonId, $key, $data)
     {
-        return $this->_updateButton($buttonId, $key, $data);
+        $this->buttonList->update($buttonId, $key, $data);
+        return $this;
     }
 
     /**
@@ -200,70 +139,10 @@ class Container extends \Magento\Backend\Block\Template
      */
     protected function _prepareLayout()
     {
-        foreach ($this->_buttons as $buttons) {
-            foreach ($buttons as $buttonId => $data) {
-                $childId = $this->_prepareButtonBlockId($buttonId);
-                $blockClassName = isset($data['class_name']) ? $data['class_name'] : null;
-                $block = $this->_getButtonChildBlock($childId, $blockClassName);
-                if (isset($data['name'])) {
-                    $data['element_name'] = $data['name'];
-                }
-                if ($block) {
-                    $block->setData($data);
-                    $this->_getButtonParentBlock($data['region'])->setChild($childId, $block);
-                }
-            }
-        }
+        $this->toolbar->pushButtons($this, $this->buttonList);
         return parent::_prepareLayout();
     }
 
-    /**
-     * Prepare block id for button's id
-     *
-     * @param string $buttonId
-     * @return string
-     */
-    protected function _prepareButtonBlockId($buttonId)
-    {
-        return $buttonId . '_button';
-    }
-
-    /**
-     * Return button parent block.
-     *
-     * @param string $region
-     * @return \Magento\Backend\Block\Template
-     */
-    protected function _getButtonParentBlock($region)
-    {
-        if (!$region || $region == 'header' || $region == 'footer') {
-            $parent = $this;
-        } elseif ($region == 'toolbar') {
-            $parent = $this->getLayout()->getBlock('page.actions.toolbar');
-        } else {
-            $parent = $this->getLayout()->getBlock($region);
-        }
-        if ($parent) {
-            return $parent;
-        }
-        return $this;
-    }
-
-    /**
-     * Adding child block with specified child's id.
-     *
-     * @param string $childId
-     * @param null|string $blockClassName
-     * @return \Magento\Backend\Block\Widget
-     */
-    protected function _getButtonChildBlock($childId, $blockClassName = null)
-    {
-        if (null === $blockClassName) {
-            $blockClassName = 'Magento\Backend\Block\Widget\Button';
-        }
-        return $this->getLayout()->createBlock($blockClassName, $this->getNameInLayout() . '-' . $childId);
-    }
-
     /**
      * Produce buttons HTML
      *
@@ -273,37 +152,18 @@ class Container extends \Magento\Backend\Block\Template
     public function getButtonsHtml($region = null)
     {
         $out = '';
-        foreach ($this->_buttons as $buttons) {
-            $_buttons = $this->_sortButtons($buttons);
-            foreach ($_buttons as $button) {
-                $data = $button['data'];
-                if ($region && isset($data['region']) && $region != $data['region']) {
+        foreach ($this->buttonList->getItems() as $buttons) {
+            /** @var \Magento\Backend\Block\Widget\Button\Item $item */
+            foreach ($buttons as $item) {
+                if ($region && $region != $item->getRegion()) {
                     continue;
                 }
-                $childId = $this->_prepareButtonBlockId($button['id']);
-                $out .= $this->getChildHtml($childId);
+                $out .= $this->getChildHtml($item->getButtonKey());
             }
         }
         return $out;
     }
 
-    /**
-     * Sort buttons by sort order
-     *
-     * @param array $buttons
-     * @return array
-     */
-    public function _sortButtons($buttons)
-    {
-        $_buttons = array();
-        foreach ($buttons as $buttonId => $data) {
-            $_buttons[$data['sort_order']]['id'] = $buttonId;
-            $_buttons[$data['sort_order']]['data'] = $data;
-        }
-        ksort($_buttons);
-        return $_buttons;
-    }
-
     /**
      * Get header text
      *
@@ -341,7 +201,7 @@ class Container extends \Magento\Backend\Block\Template
      */
     public function hasFooterButtons()
     {
-        foreach ($this->_buttons as $buttons) {
+        foreach ($this->buttonList->getItems() as $buttons) {
             foreach ($buttons as $data) {
                 if (isset($data['region']) && 'footer' == $data['region']) {
                     return true;
@@ -350,4 +210,15 @@ class Container extends \Magento\Backend\Block\Template
         }
         return false;
     }
+
+    /**
+     * Check whether button rendering is allowed in current context
+     *
+     * @param \Magento\Backend\Block\Widget\Button\Item $item
+     * @return bool
+     */
+    public function canRender(Button\Item $item)
+    {
+        return !$item->isDeleted();
+    }
 }
diff --git a/app/code/Magento/Backend/Block/Widget/ContainerInterface.php b/app/code/Magento/Backend/Block/Widget/ContainerInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd72c96c1e0901ac6f8c0758f623c42b91430291
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/ContainerInterface.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget;
+
+interface ContainerInterface extends \Magento\Backend\Block\Widget\Button\ContextInterface
+{
+    /**
+     * Public wrapper for the button list
+     *
+     * @param string $buttonId
+     * @param array $data
+     * @param integer $level
+     * @param integer $sortOrder
+     * @param string|null $region That button should be displayed in ('toolbar', 'header', 'footer', null)
+     * @return $this
+     */
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar');
+
+    /**
+     * Public wrapper for the button list
+     *
+     * @param string $buttonId
+     * @return $this
+     */
+    public function removeButton($buttonId);
+
+    /**
+     * Public wrapper for protected _updateButton method
+     *
+     * @param string $buttonId
+     * @param string|null $key
+     * @param string $data
+     * @return $this
+     */
+    public function updateButton($buttonId, $key, $data);
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Context.php b/app/code/Magento/Backend/Block/Widget/Context.php
new file mode 100644
index 0000000000000000000000000000000000000000..f5a65b938eafc21dceedde7c40461e78faeb8671
--- /dev/null
+++ b/app/code/Magento/Backend/Block/Widget/Context.php
@@ -0,0 +1,162 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Block\Widget;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class Context extends \Magento\Backend\Block\Template\Context
+{
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    protected $buttonToolbar;
+
+    /**
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @param \Magento\Framework\View\LayoutInterface $layout
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param \Magento\Framework\UrlInterface $urlBuilder
+     * @param \Magento\Framework\TranslateInterface $translator
+     * @param \Magento\Framework\App\CacheInterface $cache
+     * @param \Magento\Framework\View\DesignInterface $design
+     * @param \Magento\Framework\Session\Generic $session
+     * @param \Magento\Framework\Session\SidResolverInterface $sidResolver
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\View\Asset\Repository $assetRepo
+     * @param \Magento\Framework\View\ConfigInterface $viewConfig
+     * @param \Magento\Framework\App\Cache\StateInterface $cacheState
+     * @param \Magento\Framework\Logger $logger
+     * @param \Magento\Framework\Escaper $escaper
+     * @param \Magento\Framework\Filter\FilterManager $filterManager
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
+     * @param \Magento\Framework\App\Filesystem $filesystem
+     * @param \Magento\Framework\View\FileSystem $viewFileSystem
+     * @param \Magento\Framework\View\TemplateEnginePool $enginePool
+     * @param \Magento\Framework\App\State $appState
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\AuthorizationInterface $authorization
+     * @param \Magento\Backend\Model\Session $backendSession
+     * @param \Magento\Framework\Math\Random $mathRandom
+     * @param \Magento\Framework\Data\Form\FormKey $formKey
+     * @param \Magento\Framework\Code\NameBuilder $nameBuilder
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @param Button\ToolbarInterface $toolbar
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\App\RequestInterface $request,
+        \Magento\Framework\View\LayoutInterface $layout,
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Framework\UrlInterface $urlBuilder,
+        \Magento\Framework\TranslateInterface $translator,
+        \Magento\Framework\App\CacheInterface $cache,
+        \Magento\Framework\View\DesignInterface $design,
+        \Magento\Framework\Session\Generic $session,
+        \Magento\Framework\Session\SidResolverInterface $sidResolver,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\View\Asset\Repository $assetRepo,
+        \Magento\Framework\View\ConfigInterface $viewConfig,
+        \Magento\Framework\App\Cache\StateInterface $cacheState,
+        \Magento\Framework\Logger $logger,
+        \Magento\Framework\Escaper $escaper,
+        \Magento\Framework\Filter\FilterManager $filterManager,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
+        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
+        \Magento\Framework\App\Filesystem $filesystem,
+        \Magento\Framework\View\FileSystem $viewFileSystem,
+        \Magento\Framework\View\TemplateEnginePool $enginePool,
+        \Magento\Framework\App\State $appState,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\AuthorizationInterface $authorization,
+        \Magento\Backend\Model\Session $backendSession,
+        \Magento\Framework\Math\Random $mathRandom,
+        \Magento\Framework\Data\Form\FormKey $formKey,
+        \Magento\Framework\Code\NameBuilder $nameBuilder,
+        Button\ButtonList $buttonList,
+        Button\ToolbarInterface $toolbar
+    ) {
+        parent::__construct(
+            $request,
+            $layout,
+            $eventManager,
+            $urlBuilder,
+            $translator,
+            $cache,
+            $design,
+            $session,
+            $sidResolver,
+            $scopeConfig,
+            $assetRepo,
+            $viewConfig,
+            $cacheState,
+            $logger,
+            $escaper,
+            $filterManager,
+            $localeDate,
+            $inlineTranslation,
+            $filesystem,
+            $viewFileSystem,
+            $enginePool,
+            $appState,
+            $storeManager,
+            $authorization,
+            $backendSession,
+            $mathRandom,
+            $formKey,
+            $nameBuilder
+        );
+
+        $this->buttonList = $buttonList;
+        $this->buttonToolbar = $toolbar;
+    }
+
+    /**
+     * Get button list
+     *
+     * @return \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    public function getButtonList()
+    {
+        return $this->buttonList;
+    }
+
+    /**
+     * Get button toolbar
+     *
+     * @return \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    public function getButtonToolbar()
+    {
+        return $this->buttonToolbar;
+    }
+}
diff --git a/app/code/Magento/Backend/Block/Widget/Form/Container.php b/app/code/Magento/Backend/Block/Widget/Form/Container.php
index a3fca29babdc5739bf14b66c16a41b38b5e9f426..57c4ff39b89ed89f047ebf69f438d27979ff0e26 100644
--- a/app/code/Magento/Backend/Block/Widget/Form/Container.php
+++ b/app/code/Magento/Backend/Block/Widget/Form/Container.php
@@ -67,7 +67,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
     {
         parent::_construct();
 
-        $this->_addButton(
+        $this->addButton(
             'back',
             array(
                 'label' => __('Back'),
@@ -76,7 +76,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
             ),
             -1
         );
-        $this->_addButton(
+        $this->addButton(
             'reset',
             array('label' => __('Reset'), 'onclick' => 'setLocation(window.location.href)', 'class' => 'reset'),
             -1
@@ -85,7 +85,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
         $objId = $this->getRequest()->getParam($this->_objectId);
 
         if (!empty($objId)) {
-            $this->_addButton(
+            $this->addButton(
                 'delete',
                 array(
                     'label' => __('Delete'),
@@ -97,7 +97,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
             );
         }
 
-        $this->_addButton(
+        $this->addButton(
             'save',
             array(
                 'label' => __('Save'),
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Container.php b/app/code/Magento/Backend/Block/Widget/Grid/Container.php
index 36a1c0ef5e1fa3386121b61fee263803a9ffa0f6..3c2b92c574792ece31f08b89fa6ded6fa7766cb8 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Container.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Container.php
@@ -158,7 +158,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addNewButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'add',
             array(
                 'label' => $this->getAddButtonLabel(),
@@ -173,7 +173,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
      */
     protected function _addBackButton()
     {
-        $this->_addButton(
+        $this->addButton(
             'back',
             array(
                 'label' => $this->getBackButtonLabel(),
diff --git a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
index 10431af3952b74528ae1ab6ea28498740166d085..3cde51f10b86a6317bf821e788aff2de080c7c28 100644
--- a/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
+++ b/app/code/Magento/Backend/Block/Widget/Grid/Extended.php
@@ -467,7 +467,13 @@ class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Ba
             parent::_prepareCollection();
 
             if (!$this->_isExport) {
-                $this->getCollection()->load();
+                $filter   = $this->getParam($this->getVarNameFilter(), null);
+                if (is_string($filter)) {
+                    $this->getCollection()->removeAllItems();
+                    $this->getCollection()->loadWithFilter();
+                } else {
+                    $this->getCollection()->load();
+                }
                 $this->_afterLoadCollection();
             }
         }
diff --git a/app/code/Magento/Backend/Block/Widget/View/Container.php b/app/code/Magento/Backend/Block/Widget/View/Container.php
index a02c91f9b6457101ca228ef86174c529f470b107..5faaf075716171634ceee4d94e781e478ef7a357 100644
--- a/app/code/Magento/Backend/Block/Widget/View/Container.php
+++ b/app/code/Magento/Backend/Block/Widget/View/Container.php
@@ -53,7 +53,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
     {
         parent::_construct();
 
-        $this->_addButton(
+        $this->buttonList->add(
             'back',
             array(
                 'label' => __('Back'),
@@ -62,7 +62,7 @@ class Container extends \Magento\Backend\Block\Widget\Container
             )
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'edit',
             array(
                 'label' => __('Edit'),
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php b/app/code/Magento/Backend/Controller/Adminhtml/Ajax/Translate.php
similarity index 85%
rename from app/code/Magento/Backend/Controller/Adminhtml/Ajax.php
rename to app/code/Magento/Backend/Controller/Adminhtml/Ajax/Translate.php
index d11fec390d711f60f65c2bb3ab6f3c64f1655e39..eb016104a30e2cdbe709c1996abb5d4654773219 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Ajax.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Ajax/Translate.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,12 +19,14 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml;
+namespace Magento\Backend\Controller\Adminhtml\Ajax;
 
 use Magento\Backend\App\Action;
 
-class Ajax extends Action
+class Translate extends \Magento\Backend\App\Action
 {
     /**
      * @var \Magento\Framework\Translate\Inline\ParserInterface
@@ -48,7 +51,7 @@ class Ajax extends Action
      *
      * @return void
      */
-    public function translateAction()
+    public function execute()
     {
         $translate = (array)$this->getRequest()->getPost('translate');
 
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth.php
index a7ac7f33901520d9355c6f977e6e0d165a3ee5f9..09ba7339ae167628afa5274a03c976dea1fffde9 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Auth.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth.php
@@ -30,85 +30,6 @@ use Magento\Backend\App\AbstractAction;
  */
 class Auth extends AbstractAction
 {
-    /**
-     * Administrator login action
-     *
-     * @return void
-     */
-    public function loginAction()
-    {
-        if ($this->_auth->isLoggedIn()) {
-            if ($this->_auth->getAuthStorage()->isFirstPageAfterLogin()) {
-                $this->_auth->getAuthStorage()->setIsFirstPageAfterLogin(true);
-            }
-            $this->_redirect($this->_backendUrl->getStartupPageUrl());
-            return;
-        }
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Administrator logout action
-     *
-     * @return void
-     */
-    public function logoutAction()
-    {
-        $this->_auth->logout();
-        $this->messageManager->addSuccess(__('You have logged out.'));
-        $this->getResponse()->setRedirect($this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl());
-    }
-
-    /**
-     * Denied JSON action
-     *
-     * @return void
-     */
-    public function deniedJsonAction()
-    {
-        $this->getResponse()->representJson($this->_getDeniedJson());
-    }
-
-    /**
-     * Retrieve response for deniedJsonAction()
-     *
-     * @return string
-     */
-    protected function _getDeniedJson()
-    {
-        return $this->_objectManager->get(
-            'Magento\Core\Helper\Data'
-        )->jsonEncode(
-            array(
-                'ajaxExpired' => 1,
-                'ajaxRedirect' => $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
-            )
-        );
-    }
-
-    /**
-     * Denied IFrame action
-     *
-     * @return void
-     */
-    public function deniedIframeAction()
-    {
-        $this->getResponse()->setBody($this->_getDeniedIframe());
-    }
-
-    /**
-     * Retrieve response for deniedIframeAction()
-     *
-     * @return string
-     */
-    protected function _getDeniedIframe()
-    {
-        return '<script type="text/javascript">parent.window.location = \'' . $this->_objectManager->get(
-            'Magento\Backend\Helper\Data'
-        )->getHomePageUrl() . '\';</script>';
-    }
-
     /**
      * Check if user has permissions to access this controller
      *
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedIframe.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedIframe.php
new file mode 100644
index 0000000000000000000000000000000000000000..5271dc47cfe9e157acdc916336bdaccaf1d81ca8
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedIframe.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Auth;
+
+class DeniedIframe extends \Magento\Backend\Controller\Adminhtml\Auth
+{
+    /**
+     * Retrieve response for deniedIframeAction()
+     *
+     * @return string
+     */
+    protected function _getDeniedIframe()
+    {
+        return '<script type="text/javascript">parent.window.location = \'' . $this->_objectManager->get(
+            'Magento\Backend\Helper\Data'
+        )->getHomePageUrl() . '\';</script>';
+    }
+
+    /**
+     * Denied IFrame action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody($this->_getDeniedIframe());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedJson.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..2dbaade6560715c44491ca8aacf2413026d816c0
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth/DeniedJson.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Auth;
+
+class DeniedJson extends \Magento\Backend\Controller\Adminhtml\Auth
+{
+    /**
+     * Retrieve response for deniedJsonAction()
+     *
+     * @return string
+     */
+    protected function _getDeniedJson()
+    {
+        return $this->_objectManager->get(
+            'Magento\Core\Helper\Data'
+        )->jsonEncode(
+            array(
+                'ajaxExpired' => 1,
+                'ajaxRedirect' => $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
+            )
+        );
+    }
+
+    /**
+     * Denied JSON action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->representJson($this->_getDeniedJson());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth/Login.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth/Login.php
new file mode 100644
index 0000000000000000000000000000000000000000..2360add53c7dc421382cd52761e06e0e0c803764
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth/Login.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Auth;
+
+class Login extends \Magento\Backend\Controller\Adminhtml\Auth
+{
+    /**
+     * Administrator login action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_auth->isLoggedIn()) {
+            if ($this->_auth->getAuthStorage()->isFirstPageAfterLogin()) {
+                $this->_auth->getAuthStorage()->setIsFirstPageAfterLogin(true);
+            }
+            $this->_redirect($this->_backendUrl->getStartupPageUrl());
+            return;
+        }
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Auth/Logout.php b/app/code/Magento/Backend/Controller/Adminhtml/Auth/Logout.php
new file mode 100644
index 0000000000000000000000000000000000000000..dda6586027237f73289da47c272c9dd3a091045a
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Auth/Logout.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Auth;
+
+class Logout extends \Magento\Backend\Controller\Adminhtml\Auth
+{
+    /**
+     * Administrator logout action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_auth->logout();
+        $this->messageManager->addSuccess(__('You have logged out.'));
+        $this->getResponse()->setRedirect($this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache.php
index efa6460e38ae4723a3b1e15a29c56d67685e5294..8d1da09fc70d903ad4a80d5c6cec2fd04776326f 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Cache.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache.php
@@ -31,17 +31,17 @@ class Cache extends Action
     /**
      * @var \Magento\Framework\App\Cache\TypeListInterface
      */
-    private $_cacheTypeList;
+    protected $_cacheTypeList;
 
     /**
      * @var \Magento\Framework\App\Cache\StateInterface
      */
-    private $_cacheState;
+    protected $_cacheState;
 
     /**
      * @var \Magento\Framework\App\Cache\Frontend\Pool
      */
-    private $_cacheFrontendPool;
+    protected $_cacheFrontendPool;
 
     /**
      * @param Action\Context $context
@@ -61,147 +61,6 @@ class Cache extends Action
         $this->_cacheFrontendPool = $cacheFrontendPool;
     }
 
-    /**
-     * Display cache management grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Cache Management'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Backend::system_cache');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Flush cache storage
-     *
-     * @return void
-     */
-    public function flushAllAction()
-    {
-        $this->_eventManager->dispatch('adminhtml_cache_flush_all');
-        /** @var $cacheFrontend \Magento\Framework\Cache\FrontendInterface */
-        foreach ($this->_cacheFrontendPool as $cacheFrontend) {
-            $cacheFrontend->getBackend()->clean();
-        }
-        $this->messageManager->addSuccess(__("You flushed the cache storage."));
-        $this->_redirect('adminhtml/*');
-    }
-
-    /**
-     * Flush all magento cache
-     *
-     * @return void
-     */
-    public function flushSystemAction()
-    {
-        /** @var $cacheFrontend \Magento\Framework\Cache\FrontendInterface */
-        foreach ($this->_cacheFrontendPool as $cacheFrontend) {
-            $cacheFrontend->clean();
-        }
-        $this->_eventManager->dispatch('adminhtml_cache_flush_system');
-        $this->messageManager->addSuccess(__("The Magento cache storage has been flushed."));
-        $this->_redirect('adminhtml/*');
-    }
-
-    /**
-     * Mass action for cache enabling
-     *
-     * @return void
-     */
-    public function massEnableAction()
-    {
-        try {
-            $types = $this->getRequest()->getParam('types');
-            $updatedTypes = 0;
-            if (!is_array($types)) {
-                $types = array();
-            }
-            $this->_validateTypes($types);
-            foreach ($types as $code) {
-                if (!$this->_cacheState->isEnabled($code)) {
-                    $this->_cacheState->setEnabled($code, true);
-                    $updatedTypes++;
-                }
-            }
-            if ($updatedTypes > 0) {
-                $this->_cacheState->persist();
-                $this->messageManager->addSuccess(__("%1 cache type(s) enabled.", $updatedTypes));
-            }
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while enabling cache.'));
-        }
-        $this->_redirect('adminhtml/*');
-    }
-
-    /**
-     * Mass action for cache disabling
-     *
-     * @return void
-     */
-    public function massDisableAction()
-    {
-        try {
-            $types = $this->getRequest()->getParam('types');
-            $updatedTypes = 0;
-            if (!is_array($types)) {
-                $types = array();
-            }
-            $this->_validateTypes($types);
-            foreach ($types as $code) {
-                if ($this->_cacheState->isEnabled($code)) {
-                    $this->_cacheState->setEnabled($code, false);
-                    $updatedTypes++;
-                }
-                $this->_cacheTypeList->cleanType($code);
-            }
-            if ($updatedTypes > 0) {
-                $this->_cacheState->persist();
-                $this->messageManager->addSuccess(__("%1 cache type(s) disabled.", $updatedTypes));
-            }
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while disabling cache.'));
-        }
-        $this->_redirect('adminhtml/*');
-    }
-
-    /**
-     * Mass action for cache refresh
-     *
-     * @return void
-     */
-    public function massRefreshAction()
-    {
-        try {
-            $types = $this->getRequest()->getParam('types');
-            $updatedTypes = 0;
-            if (!is_array($types)) {
-                $types = array();
-            }
-            $this->_validateTypes($types);
-            foreach ($types as $type) {
-                $this->_cacheTypeList->cleanType($type);
-                $this->_eventManager->dispatch('adminhtml_cache_refresh_type', array('type' => $type));
-                $updatedTypes++;
-            }
-            if ($updatedTypes > 0) {
-                $this->messageManager->addSuccess(__("%1 cache type(s) refreshed.", $updatedTypes));
-            }
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while refreshing cache.'));
-        }
-        $this->_redirect('adminhtml/*');
-    }
-
     /**
      * Check whether specified cache types exist
      *
@@ -221,44 +80,6 @@ class Cache extends Action
         }
     }
 
-    /**
-     * Clean JS/css files cache
-     *
-     * @return void
-     */
-    public function cleanMediaAction()
-    {
-        try {
-            $this->_objectManager->get('Magento\Framework\View\Asset\MergeService')->cleanMergedJsCss();
-            $this->_eventManager->dispatch('clean_media_cache_after');
-            $this->messageManager->addSuccess(__('The JavaScript/CSS cache has been cleaned.'));
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while clearing the JavaScript/CSS cache.'));
-        }
-        $this->_redirect('adminhtml/*');
-    }
-
-    /**
-     * Clean JS/css files cache
-     *
-     * @return void
-     */
-    public function cleanImagesAction()
-    {
-        try {
-            $this->_objectManager->create('Magento\Catalog\Model\Product\Image')->clearCache();
-            $this->_eventManager->dispatch('clean_catalog_images_cache_after');
-            $this->messageManager->addSuccess(__('The image cache was cleaned.'));
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while clearing the image cache.'));
-        }
-        $this->_redirect('adminhtml/*');
-    }
-
     /**
      * Check if cache management is allowed
      *
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanImages.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanImages.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ef510942fccfba2d9f756853c7178ae0b7ea06d
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanImages.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Model\Exception;
+
+class CleanImages extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Clean JS/css files cache
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_objectManager->create('Magento\Catalog\Model\Product\Image')->clearCache();
+            $this->_eventManager->dispatch('clean_catalog_images_cache_after');
+            $this->messageManager->addSuccess(__('The image cache was cleaned.'));
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while clearing the image cache.'));
+        }
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanMedia.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanMedia.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc52d6b9e198d674494b3af2608a56502a22c33f
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/CleanMedia.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Model\Exception;
+
+class CleanMedia extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Clean JS/css files cache
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_objectManager->get('Magento\Framework\View\Asset\MergeService')->cleanMergedJsCss();
+            $this->_eventManager->dispatch('clean_media_cache_after');
+            $this->messageManager->addSuccess(__('The JavaScript/CSS cache has been cleaned.'));
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while clearing the JavaScript/CSS cache.'));
+        }
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushAll.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushAll.php
new file mode 100644
index 0000000000000000000000000000000000000000..19e394bee806fc84376e798ab1a2477860efe89b
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushAll.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+class FlushAll extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Flush cache storage
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_eventManager->dispatch('adminhtml_cache_flush_all');
+        /** @var $cacheFrontend \Magento\Framework\Cache\FrontendInterface */
+        foreach ($this->_cacheFrontendPool as $cacheFrontend) {
+            $cacheFrontend->getBackend()->clean();
+        }
+        $this->messageManager->addSuccess(__("You flushed the cache storage."));
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushSystem.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushSystem.php
new file mode 100644
index 0000000000000000000000000000000000000000..dded0cc2acee781f738ce72c0da763d694b20c68
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/FlushSystem.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+
+class FlushSystem extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Flush all magento cache
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $cacheFrontend \Magento\Framework\Cache\FrontendInterface */
+        foreach ($this->_cacheFrontendPool as $cacheFrontend) {
+            $cacheFrontend->clean();
+        }
+        $this->_eventManager->dispatch('adminhtml_cache_flush_system');
+        $this->messageManager->addSuccess(__("The Magento cache storage has been flushed."));
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Review.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/Index.php
similarity index 73%
rename from app/code/Magento/Customer/Controller/Review.php
rename to app/code/Magento/Backend/Controller/Adminhtml/Cache/Index.php
index c24055f8568f20870e4601d10a81eb65744a8066..117534aec60011a90c635a56b7bd7a5ecaf03cf4 100644
--- a/app/code/Magento/Customer/Controller/Review.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,30 +22,21 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Customer\Controller;
+namespace Magento\Backend\Controller\Adminhtml\Cache;
 
-/**
- * Customer reviews controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Review extends \Magento\Framework\App\Action\Action
+class Index extends \Magento\Backend\Controller\Adminhtml\Cache
 {
     /**
+     * Display cache management grid
+     *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
+        $this->_title->add(__('Cache Management'));
 
-    /**
-     * @return void
-     */
-    public function viewAction()
-    {
         $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Backend::system_cache');
         $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassDisable.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassDisable.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff2246e7712948333b04b24d4d90a3988292c567
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassDisable.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Model\Exception;
+
+class MassDisable extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Mass action for cache disabling
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $types = $this->getRequest()->getParam('types');
+            $updatedTypes = 0;
+            if (!is_array($types)) {
+                $types = array();
+            }
+            $this->_validateTypes($types);
+            foreach ($types as $code) {
+                if ($this->_cacheState->isEnabled($code)) {
+                    $this->_cacheState->setEnabled($code, false);
+                    $updatedTypes++;
+                }
+                $this->_cacheTypeList->cleanType($code);
+            }
+            if ($updatedTypes > 0) {
+                $this->_cacheState->persist();
+                $this->messageManager->addSuccess(__("%1 cache type(s) disabled.", $updatedTypes));
+            }
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while disabling cache.'));
+        }
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassEnable.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassEnable.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc52886e3bb8fca9ec92cf6c828aa789846d7dda
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassEnable.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Model\Exception;
+
+class MassEnable extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Mass action for cache enabling
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $types = $this->getRequest()->getParam('types');
+            $updatedTypes = 0;
+            if (!is_array($types)) {
+                $types = array();
+            }
+            $this->_validateTypes($types);
+            foreach ($types as $code) {
+                if (!$this->_cacheState->isEnabled($code)) {
+                    $this->_cacheState->setEnabled($code, true);
+                    $updatedTypes++;
+                }
+            }
+            if ($updatedTypes > 0) {
+                $this->_cacheState->persist();
+                $this->messageManager->addSuccess(__("%1 cache type(s) enabled.", $updatedTypes));
+            }
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while enabling cache.'));
+        }
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassRefresh.php b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassRefresh.php
new file mode 100644
index 0000000000000000000000000000000000000000..033aa1bd346e0e0145e04e02705274d287670416
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Cache/MassRefresh.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Cache;
+
+use Magento\Framework\Model\Exception;
+
+class MassRefresh extends \Magento\Backend\Controller\Adminhtml\Cache
+{
+    /**
+     * Mass action for cache refresh
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $types = $this->getRequest()->getParam('types');
+            $updatedTypes = 0;
+            if (!is_array($types)) {
+                $types = array();
+            }
+            $this->_validateTypes($types);
+            foreach ($types as $type) {
+                $this->_cacheTypeList->cleanType($type);
+                $this->_eventManager->dispatch('adminhtml_cache_refresh_type', array('type' => $type));
+                $updatedTypes++;
+            }
+            if ($updatedTypes > 0) {
+                $this->messageManager->addSuccess(__("%1 cache type(s) refreshed.", $updatedTypes));
+            }
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while refreshing cache.'));
+        }
+        $this->_redirect('adminhtml/*');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard.php
index 501ea365e0e16aa0b8e75baac824b6ce76f7d0ba..afe9c7af21c300142ff81b5a4c65e2b22b1a69b5 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard.php
@@ -31,141 +31,6 @@ namespace Magento\Backend\Controller\Adminhtml;
 
 class Dashboard extends \Magento\Backend\App\Action
 {
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context)
-    {
-        parent::__construct($context);
-    }
-
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Dashboard'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Backend::dashboard');
-        $this->_addBreadcrumb(__('Dashboard'), __('Dashboard'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Gets most viewed products list
-     *
-     * @return void
-     */
-    public function productsViewedAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Gets latest customers list
-     *
-     * @return void
-     */
-    public function customersNewestAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Gets the list of most active customers
-     *
-     * @return void
-     */
-    public function customersMostAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function ajaxBlockAction()
-    {
-        $output = '';
-        $blockTab = $this->getRequest()->getParam('block');
-        $blockClassSuffix = str_replace(
-            ' ',
-            \Magento\Framework\Autoload\IncludePath::NS_SEPARATOR,
-            ucwords(str_replace('_', ' ', $blockTab))
-        );
-        if (in_array($blockTab, array('tab_orders', 'tab_amounts', 'totals'))) {
-            $output = $this->_view->getLayout()->createBlock(
-                'Magento\\Backend\\Block\\Dashboard\\' . $blockClassSuffix
-            )->toHtml();
-        }
-        $this->getResponse()->setBody($output);
-        return;
-    }
-
-    /**
-     * Forward request for a graph image to the web-service
-     *
-     * This is done in order to include the image to a HTTPS-page regardless of web-service settings
-     *
-     * @return void
-     */
-    public function tunnelAction()
-    {
-        $error = __('invalid request');
-        $httpCode = 400;
-        $gaData = $this->_request->getParam('ga');
-        $gaHash = $this->_request->getParam('h');
-        if ($gaData && $gaHash) {
-            /** @var $helper \Magento\Backend\Helper\Dashboard\Data */
-            $helper = $this->_objectManager->get('Magento\Backend\Helper\Dashboard\Data');
-            $newHash = $helper->getChartDataHash($gaData);
-            if ($newHash == $gaHash) {
-                $params = json_decode(base64_decode(urldecode($gaData)), true);
-                if ($params) {
-                    try {
-                        /** @var $httpClient \Magento\Framework\HTTP\ZendClient */
-                        $httpClient = $this->_objectManager->create('Magento\Framework\HTTP\ZendClient');
-                        $response = $httpClient->setUri(
-                            \Magento\Backend\Block\Dashboard\Graph::API_URL
-                        )->setParameterGet(
-                            $params
-                        )->setConfig(
-                            array('timeout' => 5)
-                        )->request(
-                            'GET'
-                        );
-
-                        $headers = $response->getHeaders();
-
-                        $this->_response->setHeader(
-                            'Content-type',
-                            $headers['Content-type']
-                        )->setBody(
-                            $response->getBody()
-                        );
-                        return;
-                    } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                        $error = __('see error log for details');
-                        $httpCode = 503;
-                    }
-                }
-            }
-        }
-        $this->_response->setBody(
-            __('Service unavailable: %1', $error)
-        )->setHeader(
-            'Content-Type',
-            'text/plain; charset=UTF-8'
-        )->setHttpResponseCode(
-            $httpCode
-        );
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/AjaxBlock.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/AjaxBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5a50b3497fef909555ff35739b1c81682cf12f0
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/AjaxBlock.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class AjaxBlock extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $output = '';
+        $blockTab = $this->getRequest()->getParam('block');
+        $blockClassSuffix = str_replace(
+            ' ',
+            \Magento\Framework\Autoload\IncludePath::NS_SEPARATOR,
+            ucwords(str_replace('_', ' ', $blockTab))
+        );
+        if (in_array($blockTab, array('tab_orders', 'tab_amounts', 'totals'))) {
+            $output = $this->_view->getLayout()->createBlock(
+                'Magento\\Backend\\Block\\Dashboard\\' . $blockClassSuffix
+            )->toHtml();
+        }
+        $this->getResponse()->setBody($output);
+        return;
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersMost.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersMost.php
new file mode 100644
index 0000000000000000000000000000000000000000..3da4cce967f6aad2f512f76ef2e2e73d27111b9f
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersMost.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class CustomersMost extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * Gets the list of most active customers
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersNewest.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersNewest.php
new file mode 100644
index 0000000000000000000000000000000000000000..410d88e3fad29da00989a1dd66f5199b70c9a0c9
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/CustomersNewest.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class CustomersNewest extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * Gets latest customers list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..54b10dd4f51c1c1b6e7673c643cdd9cf573e4a9c
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Dashboard'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Backend::dashboard');
+        $this->_addBreadcrumb(__('Dashboard'), __('Dashboard'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/ProductsViewed.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/ProductsViewed.php
new file mode 100644
index 0000000000000000000000000000000000000000..571a06326db94bec76770d63472b0f152db6c6a0
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/ProductsViewed.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class ProductsViewed extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * Gets most viewed products list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf7bee63c0a284a942b6097002fda72fb6d7397b
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Dashboard/Tunnel.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
+
+class Tunnel extends \Magento\Backend\Controller\Adminhtml\Dashboard
+{
+    /**
+     * Forward request for a graph image to the web-service
+     *
+     * This is done in order to include the image to a HTTPS-page regardless of web-service settings
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $error = __('invalid request');
+        $httpCode = 400;
+        $gaData = $this->_request->getParam('ga');
+        $gaHash = $this->_request->getParam('h');
+        if ($gaData && $gaHash) {
+            /** @var $helper \Magento\Backend\Helper\Dashboard\Data */
+            $helper = $this->_objectManager->get('Magento\Backend\Helper\Dashboard\Data');
+            $newHash = $helper->getChartDataHash($gaData);
+            if ($newHash == $gaHash) {
+                $params = json_decode(base64_decode(urldecode($gaData)), true);
+                if ($params) {
+                    try {
+                        /** @var $httpClient \Magento\Framework\HTTP\ZendClient */
+                        $httpClient = $this->_objectManager->create('Magento\Framework\HTTP\ZendClient');
+                        $response = $httpClient->setUri(
+                            \Magento\Backend\Block\Dashboard\Graph::API_URL
+                        )->setParameterGet(
+                            $params
+                        )->setConfig(
+                            array('timeout' => 5)
+                        )->request(
+                            'GET'
+                        );
+
+                        $headers = $response->getHeaders();
+
+                        $this->_response->setHeader(
+                            'Content-type',
+                            $headers['Content-type']
+                        )->setBody(
+                            $response->getBody()
+                        );
+                        return;
+                    } catch (\Exception $e) {
+                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                        $error = __('see error log for details');
+                        $httpCode = 503;
+                    }
+                }
+            }
+        }
+        $this->_response->setBody(
+            __('Service unavailable: %1', $error)
+        )->setHeader(
+            'Content-Type',
+            'text/plain; charset=UTF-8'
+        )->setHttpResponseCode(
+            $httpCode
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Denied.php b/app/code/Magento/Backend/Controller/Adminhtml/Denied.php
new file mode 100644
index 0000000000000000000000000000000000000000..4a2da63ff01ab0b3782650c5f6d1163397083ecb
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Denied.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml;
+
+class Denied extends \Magento\Backend\App\Action
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('HTTP/1.1', '403 Forbidden');
+        if (!$this->_auth->isLoggedIn()) {
+            $this->_redirect('*/auth/login');
+            return;
+        }
+        $this->_view->loadLayout(array('default', 'adminhtml_denied'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Index.php
index dd154d0dc1a7efde1bf5b06863d1fa077ece9722..a21c128bbdb103b0cc47a526b8c2b33b6e23d489 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Index.php
@@ -30,90 +30,6 @@ use Magento\Backend\App\AbstractAction;
  */
 class Index extends AbstractAction
 {
-    /**
-     * Search modules list
-     *
-     * @var array
-     */
-    protected $_searchModules;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param array $searchModules
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, array $searchModules = array())
-    {
-        $this->_searchModules = $searchModules;
-        parent::__construct($context);
-    }
-
-    /**
-     * Global Search Action
-     *
-     * @return void
-     */
-    public function globalSearchAction()
-    {
-        $items = array();
-
-        if (!$this->_authorization->isAllowed('Magento_Adminhtml::global_search')) {
-            $items[] = array(
-                'id' => 'error',
-                'type' => __('Error'),
-                'name' => __('Access Denied'),
-                'description' => __('You need more permissions to do this.')
-            );
-        } else {
-            if (empty($this->_searchModules)) {
-                $items[] = array(
-                    'id' => 'error',
-                    'type' => __('Error'),
-                    'name' => __('No search modules were registered'),
-                    'description' => __(
-                        'Please make sure that all global admin search modules are installed and activated.'
-                    )
-                );
-            } else {
-                $start = $this->getRequest()->getParam('start', 1);
-                $limit = $this->getRequest()->getParam('limit', 10);
-                $query = $this->getRequest()->getParam('query', '');
-                foreach ($this->_searchModules as $searchConfig) {
-
-                    if ($searchConfig['acl'] && !$this->_authorization->isAllowed($searchConfig['acl'])) {
-                        continue;
-                    }
-
-                    $className = $searchConfig['class'];
-                    if (empty($className)) {
-                        continue;
-                    }
-                    $searchInstance = $this->_objectManager->create($className);
-                    $results = $searchInstance->setStart(
-                        $start
-                    )->setLimit(
-                        $limit
-                    )->setQuery(
-                        $query
-                    )->load()->getResults();
-                    $items = array_merge_recursive($items, $results);
-                }
-            }
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($items)
-        );
-    }
-
-    /**
-     * Change locale action
-     *
-     * @return void
-     */
-    public function changeLocaleAction()
-    {
-        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-    }
-
     /**
      * Check if user has permissions to access this controller
      *
@@ -123,15 +39,4 @@ class Index extends AbstractAction
     {
         return true;
     }
-
-    /**
-     * Admin area entry point
-     * Always redirects to the startup page url
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_redirect($this->_backendUrl->getStartupPageUrl());
-    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Index/ChangeLocale.php b/app/code/Magento/Backend/Controller/Adminhtml/Index/ChangeLocale.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a60d9f3114075211667427b771e19c5731be21d
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Index/ChangeLocale.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Index;
+
+class ChangeLocale extends \Magento\Backend\Controller\Adminhtml\Index
+{
+    /**
+     * Change locale action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Index/GlobalSearch.php b/app/code/Magento/Backend/Controller/Adminhtml/Index/GlobalSearch.php
new file mode 100644
index 0000000000000000000000000000000000000000..41e78bbc8233672bd33445ae1c985a260e6d57af
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Index/GlobalSearch.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Index;
+
+class GlobalSearch extends \Magento\Backend\Controller\Adminhtml\Index
+{
+    /**
+     * Search modules list
+     *
+     * @var array
+     */
+    protected $_searchModules;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param array $searchModules
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, array $searchModules = array())
+    {
+        $this->_searchModules = $searchModules;
+        parent::__construct($context);
+    }
+
+    /**
+     * Global Search Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $items = array();
+
+        if (!$this->_authorization->isAllowed('Magento_Adminhtml::global_search')) {
+            $items[] = array(
+                'id' => 'error',
+                'type' => __('Error'),
+                'name' => __('Access Denied'),
+                'description' => __('You need more permissions to do this.')
+            );
+        } else {
+            if (empty($this->_searchModules)) {
+                $items[] = array(
+                    'id' => 'error',
+                    'type' => __('Error'),
+                    'name' => __('No search modules were registered'),
+                    'description' => __(
+                        'Please make sure that all global admin search modules are installed and activated.'
+                    )
+                );
+            } else {
+                $start = $this->getRequest()->getParam('start', 1);
+                $limit = $this->getRequest()->getParam('limit', 10);
+                $query = $this->getRequest()->getParam('query', '');
+                foreach ($this->_searchModules as $searchConfig) {
+
+                    if ($searchConfig['acl'] && !$this->_authorization->isAllowed($searchConfig['acl'])) {
+                        continue;
+                    }
+
+                    $className = $searchConfig['class'];
+                    if (empty($className)) {
+                        continue;
+                    }
+                    $searchInstance = $this->_objectManager->create($className);
+                    $results = $searchInstance->setStart(
+                        $start
+                    )->setLimit(
+                        $limit
+                    )->setQuery(
+                        $query
+                    )->load()->getResults();
+                    $items = array_merge_recursive($items, $results);
+                }
+            }
+        }
+
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($items)
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Index/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7483782b35732716712fe04d0628a84c25215c3d
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Index/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Index;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\Index
+{
+    /**
+     * Admin area entry point
+     * Always redirects to the startup page url
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_redirect($this->_backendUrl->getStartupPageUrl());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Noroute.php b/app/code/Magento/Backend/Controller/Adminhtml/Noroute.php
index a571a311267ab806e42d486180bf9a43406c19d1..903105251e4877db3ac14e9d59a3e20624610f1e 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Noroute.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Noroute.php
@@ -24,14 +24,16 @@
  */
 namespace Magento\Backend\Controller\Adminhtml;
 
-class Noroute extends \Magento\Backend\App\Action
+class Noroute
 {
     /**
-     * Noroute action
+     * No route action
      *
+     * @param null $coreRoute
      * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function indexAction()
+    public function execute($coreRoute = null)
     {
         $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
         $this->getResponse()->setHeader('Status', '404 File not found');
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee7a23763e31aac3e5cab68772bd0c846db8d0f5
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Noroute;
+
+class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * Noroute action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
+        $this->getResponse()->setHeader('Status', '404 File not found');
+        $this->_view->loadLayout(array('default', 'adminhtml_noroute'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System.php b/app/code/Magento/Backend/Controller/Adminhtml/System.php
index 086b72886bd28e6d376b618016f8f22845d9951b..f68c49f919f4224744acb635702377f3e1c6fc98 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System.php
@@ -32,29 +32,6 @@ use Magento\Backend\App\AbstractAction;
  */
 class System extends AbstractAction
 {
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Adminhtml::system');
-        $this->_addBreadcrumb(__('System'), __('System'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function setStoreAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store');
-        if ($storeId) {
-            $this->_session->setStoreId($storeId);
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Account.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Account.php
index 7af931619cbb0950e0640473419f78337110d2c9..c33f085222f5fadc56aa66c607958e817d39fb4c 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Account.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Account.php
@@ -32,68 +32,6 @@ use Magento\Backend\App\Action;
  */
 class Account extends Action
 {
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('My Account'));
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Saving edited user information
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $userId = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser()->getId();
-        $password = (string)$this->getRequest()->getParam('password');
-        $passwordConfirmation = (string)$this->getRequest()->getParam('password_confirmation');
-        $interfaceLocale = (string)$this->getRequest()->getParam('interface_locale', false);
-
-        /** @var $user \Magento\User\Model\User */
-        $user = $this->_objectManager->create('Magento\User\Model\User')->load($userId);
-
-        $user->setId(
-            $userId
-        )->setUsername(
-            $this->getRequest()->getParam('username', false)
-        )->setFirstname(
-            $this->getRequest()->getParam('firstname', false)
-        )->setLastname(
-            $this->getRequest()->getParam('lastname', false)
-        )->setEmail(
-            strtolower($this->getRequest()->getParam('email', false))
-        );
-        if ($password !== '') {
-            $user->setPassword($password);
-            $user->setPasswordConfirmation($passwordConfirmation);
-        }
-
-        if ($this->_objectManager->get('Magento\Framework\Locale\Validator')->isValid($interfaceLocale)) {
-            $user->setInterfaceLocale($interfaceLocale);
-            $this->_objectManager->get(
-                'Magento\Backend\Model\Locale\Manager'
-            )->switchBackendInterfaceLocale(
-                $interfaceLocale
-            );
-        }
-
-        try {
-            $user->save();
-            $user->sendPasswordResetNotificationEmail();
-            $this->messageManager->addSuccess(__('The account has been saved.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addMessages($e->getMessages());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while saving account.'));
-        }
-        $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-    }
 
     /**
      * @return bool
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c0c58d2d7c2c7cb0e06047038d7cd50788c6996
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Account;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System\Account
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('My Account'));
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..65bade9c88639a370f1ff6ba0525530c51349e9f
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Account/Save.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Account;
+
+class Save extends \Magento\Backend\Controller\Adminhtml\System\Account
+{
+    /**
+     * Saving edited user information
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $userId = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser()->getId();
+        $password = (string)$this->getRequest()->getParam('password');
+        $passwordConfirmation = (string)$this->getRequest()->getParam('password_confirmation');
+        $interfaceLocale = (string)$this->getRequest()->getParam('interface_locale', false);
+
+        /** @var $user \Magento\User\Model\User */
+        $user = $this->_objectManager->create('Magento\User\Model\User')->load($userId);
+
+        $user->setId(
+            $userId
+        )->setUsername(
+            $this->getRequest()->getParam('username', false)
+        )->setFirstname(
+            $this->getRequest()->getParam('firstname', false)
+        )->setLastname(
+            $this->getRequest()->getParam('lastname', false)
+        )->setEmail(
+            strtolower($this->getRequest()->getParam('email', false))
+        );
+        if ($password !== '') {
+            $user->setPassword($password);
+            $user->setPasswordConfirmation($passwordConfirmation);
+        }
+
+        if ($this->_objectManager->get('Magento\Framework\Locale\Validator')->isValid($interfaceLocale)) {
+            $user->setInterfaceLocale($interfaceLocale);
+            $this->_objectManager->get(
+                'Magento\Backend\Model\Locale\Manager'
+            )->switchBackendInterfaceLocale(
+                $interfaceLocale
+            );
+        }
+
+        try {
+            $user->save();
+            $user->sendPasswordResetNotificationEmail();
+            $this->messageManager->addSuccess(__('The account has been saved.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addMessages($e->getMessages());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while saving account.'));
+        }
+        $this->getResponse()->setRedirect($this->getUrl("*/*/"));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php
similarity index 51%
rename from app/code/Magento/Backend/Controller/Adminhtml/System/Config.php
rename to app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php
index 27516a8592380fa784756781d72c790f7ea475a9..fb560afbdb0335662f5518e0b51021817a94c39f 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Edit.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,56 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\System;
+namespace Magento\Backend\Controller\Adminhtml\System\Config;
 
-/**
- * System Configuration controller
- */
-class Config extends AbstractConfig
+class Edit extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig
 {
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * @var \Magento\Store\Model\StoreManagerInterface
-     */
-    protected $_storeManager;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Backend\Model\Config\Structure $configStructure
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Backend\Model\Config\Structure $configStructure,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
-        \Magento\Store\Model\StoreManagerInterface $storeManager
-    ) {
-        $this->_storeManager = $storeManager;
-        $this->_fileFactory = $fileFactory;
-        parent::__construct($context, $configStructure);
-    }
-
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_forward('edit');
-    }
-
     /**
      * Edit configuration section
      *
      * @return \Magento\Framework\App\ResponseInterface|void
      */
-    public function editAction()
+    public function execute()
     {
         $this->_title->add(__('Configuration'));
 
@@ -93,25 +54,4 @@ class Config extends AbstractConfig
 
         $this->_view->renderLayout();
     }
-
-    /**
-     * Save fieldset state through AJAX
-     *
-     * @return void
-     */
-    public function stateAction()
-    {
-        if ($this->getRequest()->getParam(
-            'isAjax'
-        ) && $this->getRequest()->getParam(
-            'container'
-        ) != '' && $this->getRequest()->getParam(
-            'value'
-        ) != ''
-        ) {
-            $configState = array($this->getRequest()->getParam('container') => $this->getRequest()->getParam('value'));
-            $this->_saveState($configState);
-            $this->getResponse()->setBody('success');
-        }
-    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..157a019c8fa0fd507b7e36cd9836a7fd523146ac
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Config;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php
index 9bdc4056e330c9fe1786b35962ce43aca01efae3..2c9ca838c87bcb9626e658c4787b3707aaa1cfc1 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/Save.php
@@ -70,51 +70,6 @@ class Save extends AbstractConfig
         $this->string = $string;
     }
 
-    /**
-     * Save configuration
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        try {
-            if (false == $this->_isSectionAllowed($this->getRequest()->getParam('section'))) {
-                throw new \Exception(__('This section is not allowed.'));
-            }
-
-            // custom save logic
-            $this->_saveSection();
-            $section = $this->getRequest()->getParam('section');
-            $website = $this->getRequest()->getParam('website');
-            $store = $this->getRequest()->getParam('store');
-
-            $configData = array(
-                'section' => $section,
-                'website' => $website,
-                'store' => $store,
-                'groups' => $this->_getGroupsForSave()
-            );
-            /** @var \Magento\Backend\Model\Config $configModel  */
-            $configModel = $this->_configFactory->create(array('data' => $configData));
-            $configModel->save();
-
-            $this->messageManager->addSuccess(__('You saved the configuration.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $messages = explode("\n", $e->getMessage());
-            foreach ($messages as $message) {
-                $this->messageManager->addError($message);
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException(
-                $e,
-                __('An error occurred while saving this configuration:') . ' ' . $e->getMessage()
-            );
-        }
-
-        $this->_saveState($this->getRequest()->getPost('config_state'));
-        $this->_redirect('adminhtml/system_config/edit', array('_current' => array('section', 'website', 'store')));
-    }
-
     /**
      * Get groups for save
      *
@@ -196,4 +151,49 @@ class Save extends AbstractConfig
     {
         $this->_cache->clean();
     }
+
+    /**
+     * Save configuration
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            if (false == $this->_isSectionAllowed($this->getRequest()->getParam('section'))) {
+                throw new \Exception(__('This section is not allowed.'));
+            }
+
+            // custom save logic
+            $this->_saveSection();
+            $section = $this->getRequest()->getParam('section');
+            $website = $this->getRequest()->getParam('website');
+            $store = $this->getRequest()->getParam('store');
+
+            $configData = array(
+                'section' => $section,
+                'website' => $website,
+                'store' => $store,
+                'groups' => $this->_getGroupsForSave()
+            );
+            /** @var \Magento\Backend\Model\Config $configModel  */
+            $configModel = $this->_configFactory->create(array('data' => $configData));
+            $configModel->save();
+
+            $this->messageManager->addSuccess(__('You saved the configuration.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $messages = explode("\n", $e->getMessage());
+            foreach ($messages as $message) {
+                $this->messageManager->addError($message);
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException(
+                $e,
+                __('An error occurred while saving this configuration:') . ' ' . $e->getMessage()
+            );
+        }
+
+        $this->_saveState($this->getRequest()->getPost('config_state'));
+        $this->_redirect('adminhtml/system_config/edit', array('_current' => array('section', 'website', 'store')));
+    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php
new file mode 100644
index 0000000000000000000000000000000000000000..a43679ee9e6dfa0994ed3b355b0ef69b11d6780d
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/State.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Config;
+
+class State extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig
+{
+    /**
+     * Save fieldset state through AJAX
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam(
+            'isAjax'
+        ) && $this->getRequest()->getParam(
+            'container'
+        ) != '' && $this->getRequest()->getParam(
+            'value'
+        ) != ''
+        ) {
+            $configState = array($this->getRequest()->getParam('container') => $this->getRequest()->getParam('value'));
+            $this->_saveState($configState);
+            $this->getResponse()->setBody('success');
+        }
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php
index ec91e6b450147f8fc1953553d8307716b2ce58c1..391b2b95e6f7d992c6ab9520e1cd49fc3f3e0fcb 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage.php
@@ -50,136 +50,4 @@ class Storage extends \Magento\Backend\App\Action
     {
         return $this->_getSyncSingleton()->getSyncFlag();
     }
-
-    /**
-     * Synchronize action between storages
-     *
-     * @return void
-     */
-    public function synchronizeAction()
-    {
-        session_write_close();
-
-        $requestStorage = $this->getRequest()->getParam('storage');
-        $requestConnection = $this->getRequest()->getParam('connection');
-        if (!isset($requestStorage)) {
-            return;
-        }
-
-        $flag = $this->_getSyncFlag();
-        if ($flag &&
-            $flag->getState() == \Magento\Core\Model\File\Storage\Flag::STATE_RUNNING &&
-            $flag->getLastUpdate() &&
-            time() <= strtotime(
-                $flag->getLastUpdate()
-            ) + \Magento\Core\Model\File\Storage\Flag::FLAG_TTL
-        ) {
-            return;
-        }
-
-        $flag->setState(\Magento\Core\Model\File\Storage\Flag::STATE_RUNNING)->setFlagData(array())->save();
-
-        $storage = array('type' => $requestStorage);
-        if (isset($requestConnection) && !empty($requestConnection)) {
-            $storage['connection'] = $requestConnection;
-        }
-
-        try {
-            $this->_getSyncSingleton()->synchronize($storage);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $flag->passError($e);
-        }
-
-        $flag->setState(\Magento\Core\Model\File\Storage\Flag::STATE_FINISHED)->save();
-    }
-
-    /**
-     * Retrieve synchronize process state and it's parameters in json format
-     *
-     * @return void
-     */
-    public function statusAction()
-    {
-        $result = array();
-        $flag = $this->_getSyncFlag();
-
-        if ($flag) {
-            $state = $flag->getState();
-
-            switch ($state) {
-                case \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE:
-                    $flagData = $flag->getFlagData();
-                    if (is_array($flagData)) {
-                        if (isset($flagData['destination']) && !empty($flagData['destination'])) {
-                            $result['destination'] = $flagData['destination'];
-                        }
-                    }
-                    $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
-                    break;
-                case \Magento\Core\Model\File\Storage\Flag::STATE_RUNNING:
-                    if (!$flag->getLastUpdate() || time() <= strtotime(
-                        $flag->getLastUpdate()
-                    ) + \Magento\Core\Model\File\Storage\Flag::FLAG_TTL
-                    ) {
-                        $flagData = $flag->getFlagData();
-                        if (is_array(
-                            $flagData
-                        ) && isset(
-                            $flagData['source']
-                        ) && !empty($flagData['source']) && isset(
-                            $flagData['destination']
-                        ) && !empty($flagData['destination'])
-                        ) {
-                            $result['message'] = __(
-                                'Synchronizing %1 to %2',
-                                $flagData['source'],
-                                $flagData['destination']
-                            );
-                        } else {
-                            $result['message'] = __('Synchronizing...');
-                        }
-                        break;
-                    } else {
-                        $flagData = $flag->getFlagData();
-                        if (is_array(
-                            $flagData
-                        ) && !(isset(
-                            $flagData['timeout_reached']
-                        ) && $flagData['timeout_reached'])
-                        ) {
-                            $this->_objectManager->get(
-                                'Magento\Framework\Logger'
-                            )->logException(
-                                new \Magento\Framework\Exception(
-                                    __('The timeout limit for response from synchronize process was reached.')
-                                )
-                            );
-
-                            $state = \Magento\Core\Model\File\Storage\Flag::STATE_FINISHED;
-                            $flagData['has_errors'] = true;
-                            $flagData['timeout_reached'] = true;
-                            $flag->setState($state)->setFlagData($flagData)->save();
-                        }
-                    }
-                    // fall-through intentional
-                case \Magento\Core\Model\File\Storage\Flag::STATE_FINISHED:
-                case \Magento\Core\Model\File\Storage\Flag::STATE_NOTIFIED:
-                    $flagData = $flag->getFlagData();
-                    if (!isset($flagData['has_errors'])) {
-                        $flagData['has_errors'] = false;
-                    }
-                    $result['has_errors'] = $flagData['has_errors'];
-                    break;
-                default:
-                    $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
-                    break;
-            }
-        } else {
-            $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
-        }
-        $result['state'] = $state;
-        $result = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result);
-        $this->_response->representJson($result);
-    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
new file mode 100644
index 0000000000000000000000000000000000000000..1dd2083c8e273e40ede22e4a57c01b4937b90288
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Status.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Config\System\Storage;
+
+class Status extends \Magento\Backend\Controller\Adminhtml\System\Config\System\Storage
+{
+    /**
+     * Retrieve synchronize process state and it's parameters in json format
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $result = array();
+        $flag = $this->_getSyncFlag();
+
+        if ($flag) {
+            $state = $flag->getState();
+
+            switch ($state) {
+                case \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE:
+                    $flagData = $flag->getFlagData();
+                    if (is_array($flagData)) {
+                        if (isset($flagData['destination']) && !empty($flagData['destination'])) {
+                            $result['destination'] = $flagData['destination'];
+                        }
+                    }
+                    $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
+                    break;
+                case \Magento\Core\Model\File\Storage\Flag::STATE_RUNNING:
+                    if (!$flag->getLastUpdate() || time() <= strtotime(
+                        $flag->getLastUpdate()
+                    ) + \Magento\Core\Model\File\Storage\Flag::FLAG_TTL
+                    ) {
+                        $flagData = $flag->getFlagData();
+                        if (is_array(
+                            $flagData
+                        ) && isset(
+                            $flagData['source']
+                        ) && !empty($flagData['source']) && isset(
+                            $flagData['destination']
+                        ) && !empty($flagData['destination'])
+                        ) {
+                            $result['message'] = __(
+                                'Synchronizing %1 to %2',
+                                $flagData['source'],
+                                $flagData['destination']
+                            );
+                        } else {
+                            $result['message'] = __('Synchronizing...');
+                        }
+                        break;
+                    } else {
+                        $flagData = $flag->getFlagData();
+                        if (is_array(
+                            $flagData
+                        ) && !(isset(
+                            $flagData['timeout_reached']
+                        ) && $flagData['timeout_reached'])
+                        ) {
+                            $this->_objectManager->get(
+                                'Magento\Framework\Logger'
+                            )->logException(
+                                new \Magento\Framework\Exception(
+                                    __('The timeout limit for response from synchronize process was reached.')
+                                )
+                            );
+
+                            $state = \Magento\Core\Model\File\Storage\Flag::STATE_FINISHED;
+                            $flagData['has_errors'] = true;
+                            $flagData['timeout_reached'] = true;
+                            $flag->setState($state)->setFlagData($flagData)->save();
+                        }
+                    }
+                    // fall-through intentional
+                case \Magento\Core\Model\File\Storage\Flag::STATE_FINISHED:
+                case \Magento\Core\Model\File\Storage\Flag::STATE_NOTIFIED:
+                    $flagData = $flag->getFlagData();
+                    if (!isset($flagData['has_errors'])) {
+                        $flagData['has_errors'] = false;
+                    }
+                    $result['has_errors'] = $flagData['has_errors'];
+                    break;
+                default:
+                    $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
+                    break;
+            }
+        } else {
+            $state = \Magento\Core\Model\File\Storage\Flag::STATE_INACTIVE;
+        }
+        $result['state'] = $state;
+        $result = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result);
+        $this->_response->representJson($result);
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
new file mode 100644
index 0000000000000000000000000000000000000000..ace9608379da4e1113254ba4bf9fd42b0026bd64
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Config/System/Storage/Synchronize.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Config\System\Storage;
+
+class Synchronize extends \Magento\Backend\Controller\Adminhtml\System\Config\System\Storage
+{
+    /**
+     * Synchronize action between storages
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        session_write_close();
+
+        $requestStorage = $this->getRequest()->getParam('storage');
+        $requestConnection = $this->getRequest()->getParam('connection');
+        if (!isset($requestStorage)) {
+            return;
+        }
+
+        $flag = $this->_getSyncFlag();
+        if ($flag &&
+            $flag->getState() == \Magento\Core\Model\File\Storage\Flag::STATE_RUNNING &&
+            $flag->getLastUpdate() &&
+            time() <= strtotime(
+                $flag->getLastUpdate()
+            ) + \Magento\Core\Model\File\Storage\Flag::FLAG_TTL
+        ) {
+            return;
+        }
+
+        $flag->setState(\Magento\Core\Model\File\Storage\Flag::STATE_RUNNING)->setFlagData(array())->save();
+
+        $storage = array('type' => $requestStorage);
+        if (isset($requestConnection) && !empty($requestConnection)) {
+            $storage['connection'] = $requestConnection;
+        }
+
+        try {
+            $this->_getSyncSingleton()->synchronize($storage);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $flag->passError($e);
+        }
+
+        $flag->setState(\Magento\Core\Model\File\Storage\Flag::STATE_FINISHED)->save();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design.php
index 74cc9227ee27d7b54ed02169c53d20fdcf107595..a2bdea502fd77d5bf62210830b0b321eb26d0c08 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Design.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design.php
@@ -54,119 +54,6 @@ class Design extends Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Store Design'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Backend::system_design_schedule');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Store Design'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Backend::system_design_schedule');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
-        $id = (int)$this->getRequest()->getParam('id');
-        $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface');
-
-        if ($id) {
-            $design->load($id);
-        }
-
-        $this->_title->add($design->getId() ? __('Edit Store Design Change') : __('New Store Design Change'));
-
-        $this->_coreRegistry->register('design', $design);
-
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Design\Edit'));
-        $this->_addLeft(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Design\Edit\Tabs', 'design_tabs')
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $data['design'] = $this->_filterPostData($data['design']);
-            $id = (int)$this->getRequest()->getParam('id');
-
-            $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface');
-            if ($id) {
-                $design->load($id);
-            }
-
-            $design->setData($data['design']);
-            if ($id) {
-                $design->setId($id);
-            }
-            try {
-                $design->save();
-                $this->_eventManager->dispatch('theme_save_after');
-                $this->messageManager->addSuccess(__('You saved the design change.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setDesignData($data);
-                $this->_redirect('adminhtml/*/edit', array('id' => $design->getId()));
-                return;
-            }
-        }
-
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface')->load($id);
-
-            try {
-                $design->delete();
-                $this->messageManager->addSuccess(__('You deleted the design change.'));
-            } catch (\Magento\Framework\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __("Cannot delete the design change."));
-            }
-        }
-        $this->getResponse()->setRedirect($this->getUrl('adminhtml/*/'));
-    }
-
     /**
      * @return bool
      */
@@ -174,21 +61,4 @@ class Design extends Action
     {
         return $this->_authorization->isAllowed('Magento_Adminhtml::design');
     }
-
-    /**
-     * Filtering posted data. Converting localized data if needed
-     *
-     * @param array $data
-     * @return array|null
-     */
-    protected function _filterPostData($data)
-    {
-        $inputFilter = new \Zend_Filter_Input(
-            array('date_from' => $this->dateFilter, 'date_to' => $this->dateFilter),
-            array(),
-            $data
-        );
-        $data = $inputFilter->getUnescaped();
-        return $data;
-    }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Delete.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..611118991f2dab5ae7948cff23694f3c5c88c7e5
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Delete.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class Delete extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface')->load($id);
+
+            try {
+                $design->delete();
+                $this->messageManager->addSuccess(__('You deleted the design change.'));
+            } catch (\Magento\Framework\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __("Cannot delete the design change."));
+            }
+        }
+        $this->getResponse()->setRedirect($this->getUrl('adminhtml/*/'));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..842c6df2ba9d16fd7d2207656667a90ee05a300c
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Edit.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class Edit extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Store Design'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Backend::system_design_schedule');
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $id = (int)$this->getRequest()->getParam('id');
+        $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface');
+
+        if ($id) {
+            $design->load($id);
+        }
+
+        $this->_title->add($design->getId() ? __('Edit Store Design Change') : __('New Store Design Change'));
+
+        $this->_coreRegistry->register('design', $design);
+
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Design\Edit'));
+        $this->_addLeft(
+            $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Design\Edit\Tabs', 'design_tabs')
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Grid.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..121cbdf223bba9f9d18a2044f27d58f2e2960885
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Grid.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class Grid extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..97cb56eb785f48d03f00d5c882cc9d43d8e892dc
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Store Design'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Backend::system_design_schedule');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/NewAction.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a70112da9ea15ef986bb4609cbb5ce705099d4e
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class NewAction extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..c96ba5ddf40999dc1df959715b591be8e9e087ca
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Design/Save.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Design;
+
+class Save extends \Magento\Backend\Controller\Adminhtml\System\Design
+{
+    /**
+     * Filtering posted data. Converting localized data if needed
+     *
+     * @param array $data
+     * @return array|null
+     */
+    protected function _filterPostData($data)
+    {
+        $inputFilter = new \Zend_Filter_Input(
+            array('date_from' => $this->dateFilter, 'date_to' => $this->dateFilter),
+            array(),
+            $data
+        );
+        $data = $inputFilter->getUnescaped();
+        return $data;
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $data['design'] = $this->_filterPostData($data['design']);
+            $id = (int)$this->getRequest()->getParam('id');
+
+            $design = $this->_objectManager->create('Magento\Framework\App\DesignInterface');
+            if ($id) {
+                $design->load($id);
+            }
+
+            $design->setData($data['design']);
+            if ($id) {
+                $design->setId($id);
+            }
+            try {
+                $design->save();
+                $this->_eventManager->dispatch('theme_save_after');
+                $this->messageManager->addSuccess(__('You saved the design change.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setDesignData($data);
+                $this->_redirect('adminhtml/*/edit', array('id' => $design->getId()));
+                return;
+            }
+        }
+
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..c44c9c102bed6a31c0430957df2a7779824632c8
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Adminhtml::system');
+        $this->_addBreadcrumb(__('System'), __('System'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/SetStore.php b/app/code/Magento/Backend/Controller/Adminhtml/System/SetStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..30dd712bc062f9ff6b9c226d831424a421ce72f4
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/SetStore.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System;
+
+class SetStore extends \Magento\Backend\Controller\Adminhtml\System
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store');
+        if ($storeId) {
+            $this->_session->setStoreId($storeId);
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php
index 0e4920afbdffaeed27a5fa184f28a035b18dc280..ffd1a9df18f98661b20d274ad3cb7a512237a122 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store.php
@@ -80,455 +80,6 @@ class Store extends Action
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Stores'));
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newWebsiteAction()
-    {
-        $this->_coreRegistry->register('store_type', 'website');
-        $this->_forward('newStore');
-    }
-
-    /**
-     * @return void
-     */
-    public function newGroupAction()
-    {
-        $this->_coreRegistry->register('store_type', 'group');
-        $this->_forward('newStore');
-    }
-
-    /**
-     * @return void
-     */
-    public function newStoreAction()
-    {
-        if (!$this->_coreRegistry->registry('store_type')) {
-            $this->_coreRegistry->register('store_type', 'store');
-        }
-        $this->_coreRegistry->register('store_action', 'add');
-        $this->_forward('editStore');
-    }
-
-    /**
-     * @return void
-     */
-    public function editWebsiteAction()
-    {
-        $this->_coreRegistry->register('store_type', 'website');
-        $this->_forward('editStore');
-    }
-
-    /**
-     * @return void
-     */
-    public function editGroupAction()
-    {
-        $this->_coreRegistry->register('store_type', 'group');
-        $this->_forward('editStore');
-    }
-
-    /**
-     * @return void
-     */
-    public function editStoreAction()
-    {
-        $this->_title->add(__('Stores'));
-
-        if ($this->_getSession()->getPostData()) {
-            $this->_coreRegistry->register('store_post_data', $this->_getSession()->getPostData());
-            $this->_getSession()->unsPostData();
-        }
-        if (!$this->_coreRegistry->registry('store_type')) {
-            $this->_coreRegistry->register('store_type', 'store');
-        }
-        if (!$this->_coreRegistry->registry('store_action')) {
-            $this->_coreRegistry->register('store_action', 'edit');
-        }
-        switch ($this->_coreRegistry->registry('store_type')) {
-            case 'website':
-                $itemId = $this->getRequest()->getParam('website_id', null);
-                $model = $this->_objectManager->create('Magento\Store\Model\Website');
-                $title = __("Web Site");
-                $notExists = __("The website does not exist.");
-                $codeBase = __('Before modifying the website code please make sure that it is not used in index.php.');
-                break;
-            case 'group':
-                $itemId = $this->getRequest()->getParam('group_id', null);
-                $model = $this->_objectManager->create('Magento\Store\Model\Group');
-                $title = __("Store");
-                $notExists = __("The store does not exist");
-                $codeBase = false;
-                break;
-            case 'store':
-                $itemId = $this->getRequest()->getParam('store_id', null);
-                $model = $this->_objectManager->create('Magento\Store\Model\Store');
-                $title = __("Store View");
-                $notExists = __("Store view doesn't exist");
-                $codeBase = __(
-                    'Before modifying the store view code please make sure that it is not used in index.php.'
-                );
-                break;
-            default:
-                break;
-        }
-        if (null !== $itemId) {
-            $model->load($itemId);
-        }
-
-        if ($model->getId() || $this->_coreRegistry->registry('store_action') == 'add') {
-            $this->_coreRegistry->register('store_data', $model);
-
-            if ($this->_coreRegistry->registry('store_action') == 'add') {
-                $this->_title->add(__('New ') . $title);
-            } else {
-                $this->_title->add($model->getName());
-            }
-
-            if ($this->_coreRegistry->registry('store_action') == 'edit' && $codeBase && !$model->isReadOnly()) {
-                $this->messageManager->addNotice($codeBase);
-            }
-
-            $this->_initAction()->_addContent(
-                $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Store\Edit')
-            );
-            $this->_view->renderLayout();
-        } else {
-            $this->messageManager->addError($notExists);
-            $this->_redirect('adminhtml/*/');
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        if ($this->getRequest()->isPost() && ($postData = $this->getRequest()->getPost())) {
-            if (empty($postData['store_type']) || empty($postData['store_action'])) {
-                $this->_redirect('adminhtml/*/');
-                return;
-            }
-
-            try {
-                switch ($postData['store_type']) {
-                    case 'website':
-                        $postData['website']['name'] = $this->filterManager->removeTags($postData['website']['name']);
-                        $websiteModel = $this->_objectManager->create('Magento\Store\Model\Website');
-                        if ($postData['website']['website_id']) {
-                            $websiteModel->load($postData['website']['website_id']);
-                        }
-                        $websiteModel->setData($postData['website']);
-                        if ($postData['website']['website_id'] == '') {
-                            $websiteModel->setId(null);
-                        }
-
-                        $websiteModel->save();
-                        $this->messageManager->addSuccess(__('The website has been saved.'));
-                        break;
-
-                    case 'group':
-                        $postData['group']['name'] = $this->filterManager->removeTags($postData['group']['name']);
-                        $groupModel = $this->_objectManager->create('Magento\Store\Model\Group');
-                        if ($postData['group']['group_id']) {
-                            $groupModel->load($postData['group']['group_id']);
-                        }
-                        $groupModel->setData($postData['group']);
-                        if ($postData['group']['group_id'] == '') {
-                            $groupModel->setId(null);
-                        }
-
-                        $groupModel->save();
-
-                        $this->_eventManager->dispatch('store_group_save', array('group' => $groupModel));
-
-                        $this->messageManager->addSuccess(__('The store has been saved.'));
-                        break;
-
-                    case 'store':
-                        $eventName = 'store_edit';
-                        $storeModel = $this->_objectManager->create('Magento\Store\Model\Store');
-                        $postData['store']['name'] = $this->filterManager->removeTags($postData['store']['name']);
-                        if ($postData['store']['store_id']) {
-                            $storeModel->load($postData['store']['store_id']);
-                        }
-                        $storeModel->setData($postData['store']);
-                        if ($postData['store']['store_id'] == '') {
-                            $storeModel->setId(null);
-                            $eventName = 'store_add';
-                        }
-                        $groupModel = $this->_objectManager->create(
-                            'Magento\Store\Model\Group'
-                        )->load(
-                            $storeModel->getGroupId()
-                        );
-                        $storeModel->setWebsiteId($groupModel->getWebsiteId());
-                        $storeModel->save();
-
-                        $this->_objectManager->get('Magento\Store\Model\StoreManager')->reinitStores();
-
-                        $this->_eventManager->dispatch($eventName, array('store' => $storeModel));
-
-                        $this->messageManager->addSuccess(__('The store view has been saved'));
-                        break;
-                    default:
-                        $this->_redirect('adminhtml/*/');
-                        return;
-                }
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_getSession()->setPostData($postData);
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('An error occurred while saving. Please review the error log.')
-                );
-                $this->_getSession()->setPostData($postData);
-            }
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            return;
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteWebsiteAction()
-    {
-        $this->_title->add(__('Delete Web Site'));
-
-        $itemId = $this->getRequest()->getParam('item_id', null);
-        if (!($model = $this->_objectManager->create('Magento\Store\Model\Website')->load($itemId))) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This website cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $itemId));
-            return;
-        }
-
-        $this->_addDeletionNotice('website');
-
-        $this->_initAction()->_addBreadcrumb(
-            __('Delete Web Site'),
-            __('Delete Web Site')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Backend\Block\System\Store\Delete'
-            )->setFormActionUrl(
-                $this->getUrl('adminhtml/*/deleteWebsitePost')
-            )->setBackUrl(
-                $this->getUrl('adminhtml/*/editWebsite', array('website_id' => $itemId))
-            )->setStoreTypeTitle(
-                __('Web Site')
-            )->setDataObject(
-                $model
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteGroupAction()
-    {
-        $this->_title->add(__('Delete Store'));
-
-        $itemId = $this->getRequest()->getParam('item_id', null);
-        if (!($model = $this->_objectManager->create('Magento\Store\Model\Group')->load($itemId))) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This store cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editGroup', array('group_id' => $itemId));
-            return;
-        }
-
-        $this->_addDeletionNotice('store');
-
-        $this->_initAction()->_addBreadcrumb(
-            __('Delete Store'),
-            __('Delete Store')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Backend\Block\System\Store\Delete'
-            )->setFormActionUrl(
-                $this->getUrl('adminhtml/*/deleteGroupPost')
-            )->setBackUrl(
-                $this->getUrl('adminhtml/*/editGroup', array('group_id' => $itemId))
-            )->setStoreTypeTitle(
-                __('Store')
-            )->setDataObject(
-                $model
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteStoreAction()
-    {
-        $this->_title->add(__('Delete Store View'));
-
-        $itemId = $this->getRequest()->getParam('item_id', null);
-        if (!($model = $this->_objectManager->create('Magento\Store\Model\Store')->load($itemId))) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This store view cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editStore', array('store_id' => $itemId));
-            return;
-        }
-
-        $this->_addDeletionNotice('store view');
-
-        $this->_initAction()->_addBreadcrumb(
-            __('Delete Store View'),
-            __('Delete Store View')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Backend\Block\System\Store\Delete'
-            )->setFormActionUrl(
-                $this->getUrl('adminhtml/*/deleteStorePost')
-            )->setBackUrl(
-                $this->getUrl('adminhtml/*/editStore', array('store_id' => $itemId))
-            )->setStoreTypeTitle(
-                __('Store View')
-            )->setDataObject(
-                $model
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteWebsitePostAction()
-    {
-        $itemId = $this->getRequest()->getParam('item_id');
-        $model = $this->_objectManager->create('Magento\Store\Model\Website');
-        $model->load($itemId);
-
-        if (!$model) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This website cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $model->getId()));
-            return;
-        }
-
-        $this->_backupDatabase('*/*/editWebsite', array('website_id' => $itemId));
-
-        try {
-            $model->delete();
-            $this->messageManager->addSuccess(__('The website has been deleted.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to delete website. Please, try again later.'));
-        }
-        $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $itemId));
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteGroupPostAction()
-    {
-        $itemId = $this->getRequest()->getParam('item_id');
-
-        if (!($model = $this->_objectManager->create('Magento\Store\Model\Group')->load($itemId))) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This store cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editGroup', array('group_id' => $model->getId()));
-            return;
-        }
-
-        $this->_backupDatabase('*/*/editGroup', array('group_id' => $itemId));
-
-        try {
-            $model->delete();
-            $this->messageManager->addSuccess(__('The store has been deleted.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to delete store. Please, try again later.'));
-        }
-        $this->_redirect('adminhtml/*/editGroup', array('group_id' => $itemId));
-    }
-
-    /**
-     * Delete store view post action
-     *
-     * @return void
-     */
-    public function deleteStorePostAction()
-    {
-        $itemId = $this->getRequest()->getParam('item_id');
-
-        if (!($model = $this->_objectManager->create('Magento\Store\Model\Store')->load($itemId))) {
-            $this->messageManager->addError(__('Unable to proceed. Please, try again'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        if (!$model->isCanDelete()) {
-            $this->messageManager->addError(__('This store view cannot be deleted.'));
-            $this->_redirect('adminhtml/*/editStore', array('store_id' => $model->getId()));
-            return;
-        }
-
-        $this->_backupDatabase('*/*/editStore', array('store_id' => $itemId));
-
-        try {
-            $model->delete();
-
-            $this->_eventManager->dispatch('store_delete', array('store' => $model));
-
-            $this->messageManager->addSuccess(__('The store view has been deleted.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to delete store view. Please, try again later.'));
-        }
-        $this->_redirect('adminhtml/*/editStore', array('store_id' => $itemId));
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroup.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e969699f46be927e0a56492094441be34691135
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroup.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteGroup extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Delete Store'));
+
+        $itemId = $this->getRequest()->getParam('item_id', null);
+        if (!($model = $this->_objectManager->create('Magento\Store\Model\Group')->load($itemId))) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This store cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editGroup', array('group_id' => $itemId));
+            return;
+        }
+
+        $this->_addDeletionNotice('store');
+
+        $this->_initAction()->_addBreadcrumb(
+            __('Delete Store'),
+            __('Delete Store')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Backend\Block\System\Store\Delete'
+            )->setFormActionUrl(
+                $this->getUrl('adminhtml/*/deleteGroupPost')
+            )->setBackUrl(
+                $this->getUrl('adminhtml/*/editGroup', array('group_id' => $itemId))
+            )->setStoreTypeTitle(
+                __('Store')
+            )->setDataObject(
+                $model
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroupPost.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroupPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..5995c756ec45c2e169366ad4367db0e8f631a8fe
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteGroupPost.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteGroupPost extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $itemId = $this->getRequest()->getParam('item_id');
+
+        if (!($model = $this->_objectManager->create('Magento\Store\Model\Group')->load($itemId))) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This store cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editGroup', array('group_id' => $model->getId()));
+            return;
+        }
+
+        $this->_backupDatabase('*/*/editGroup', array('group_id' => $itemId));
+
+        try {
+            $model->delete();
+            $this->messageManager->addSuccess(__('The store has been deleted.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to delete store. Please, try again later.'));
+        }
+        $this->_redirect('adminhtml/*/editGroup', array('group_id' => $itemId));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStore.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee1c4e3243038e99a8eaabe20a7e76abc8022110
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStore.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteStore extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Delete Store View'));
+
+        $itemId = $this->getRequest()->getParam('item_id', null);
+        if (!($model = $this->_objectManager->create('Magento\Store\Model\Store')->load($itemId))) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This store view cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editStore', array('store_id' => $itemId));
+            return;
+        }
+
+        $this->_addDeletionNotice('store view');
+
+        $this->_initAction()->_addBreadcrumb(
+            __('Delete Store View'),
+            __('Delete Store View')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Backend\Block\System\Store\Delete'
+            )->setFormActionUrl(
+                $this->getUrl('adminhtml/*/deleteStorePost')
+            )->setBackUrl(
+                $this->getUrl('adminhtml/*/editStore', array('store_id' => $itemId))
+            )->setStoreTypeTitle(
+                __('Store View')
+            )->setDataObject(
+                $model
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..1fd7a689724c13ba7b24b996b1a4b22ec81e736b
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteStorePost.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteStorePost extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * Delete store view post action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $itemId = $this->getRequest()->getParam('item_id');
+
+        if (!($model = $this->_objectManager->create('Magento\Store\Model\Store')->load($itemId))) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This store view cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editStore', array('store_id' => $model->getId()));
+            return;
+        }
+
+        $this->_backupDatabase('*/*/editStore', array('store_id' => $itemId));
+
+        try {
+            $model->delete();
+
+            $this->_eventManager->dispatch('store_delete', array('store' => $model));
+
+            $this->messageManager->addSuccess(__('The store view has been deleted.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to delete store view. Please, try again later.'));
+        }
+        $this->_redirect('adminhtml/*/editStore', array('store_id' => $itemId));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsite.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsite.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a99a2925e0982eaca32621ad5863617384b076d
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsite.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteWebsite extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Delete Web Site'));
+
+        $itemId = $this->getRequest()->getParam('item_id', null);
+        if (!($model = $this->_objectManager->create('Magento\Store\Model\Website')->load($itemId))) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This website cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $itemId));
+            return;
+        }
+
+        $this->_addDeletionNotice('website');
+
+        $this->_initAction()->_addBreadcrumb(
+            __('Delete Web Site'),
+            __('Delete Web Site')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Backend\Block\System\Store\Delete'
+            )->setFormActionUrl(
+                $this->getUrl('adminhtml/*/deleteWebsitePost')
+            )->setBackUrl(
+                $this->getUrl('adminhtml/*/editWebsite', array('website_id' => $itemId))
+            )->setStoreTypeTitle(
+                __('Web Site')
+            )->setDataObject(
+                $model
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsitePost.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsitePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..be99235d5effa540008eac84a123c134a7fc16f8
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/DeleteWebsitePost.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class DeleteWebsitePost extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $itemId = $this->getRequest()->getParam('item_id');
+        $model = $this->_objectManager->create('Magento\Store\Model\Website');
+        $model->load($itemId);
+
+        if (!$model) {
+            $this->messageManager->addError(__('Unable to proceed. Please, try again'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        if (!$model->isCanDelete()) {
+            $this->messageManager->addError(__('This website cannot be deleted.'));
+            $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $model->getId()));
+            return;
+        }
+
+        $this->_backupDatabase('*/*/editWebsite', array('website_id' => $itemId));
+
+        try {
+            $model->delete();
+            $this->messageManager->addSuccess(__('The website has been deleted.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to delete website. Please, try again later.'));
+        }
+        $this->_redirect('adminhtml/*/editWebsite', array('website_id' => $itemId));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditGroup.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d0e0e9d72033a12e289ccba8c3b99be805e716b
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditGroup.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class EditGroup extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_coreRegistry->register('store_type', 'group');
+        $this->_forward('editStore');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditStore.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..43b5e9e33e100982dd6b8ed2c42e222a5f3b6cab
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditStore.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class EditStore extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Stores'));
+
+        if ($this->_getSession()->getPostData()) {
+            $this->_coreRegistry->register('store_post_data', $this->_getSession()->getPostData());
+            $this->_getSession()->unsPostData();
+        }
+        if (!$this->_coreRegistry->registry('store_type')) {
+            $this->_coreRegistry->register('store_type', 'store');
+        }
+        if (!$this->_coreRegistry->registry('store_action')) {
+            $this->_coreRegistry->register('store_action', 'edit');
+        }
+        switch ($this->_coreRegistry->registry('store_type')) {
+            case 'website':
+                $itemId = $this->getRequest()->getParam('website_id', null);
+                $model = $this->_objectManager->create('Magento\Store\Model\Website');
+                $title = __("Web Site");
+                $notExists = __("The website does not exist.");
+                $codeBase = __('Before modifying the website code please make sure that it is not used in index.php.');
+                break;
+            case 'group':
+                $itemId = $this->getRequest()->getParam('group_id', null);
+                $model = $this->_objectManager->create('Magento\Store\Model\Group');
+                $title = __("Store");
+                $notExists = __("The store does not exist");
+                $codeBase = false;
+                break;
+            case 'store':
+                $itemId = $this->getRequest()->getParam('store_id', null);
+                $model = $this->_objectManager->create('Magento\Store\Model\Store');
+                $title = __("Store View");
+                $notExists = __("Store view doesn't exist");
+                $codeBase = __(
+                    'Before modifying the store view code please make sure that it is not used in index.php.'
+                );
+                break;
+            default:
+                break;
+        }
+        if (null !== $itemId) {
+            $model->load($itemId);
+        }
+
+        if ($model->getId() || $this->_coreRegistry->registry('store_action') == 'add') {
+            $this->_coreRegistry->register('store_data', $model);
+
+            if ($this->_coreRegistry->registry('store_action') == 'add') {
+                $this->_title->add(__('New ') . $title);
+            } else {
+                $this->_title->add($model->getName());
+            }
+
+            if ($this->_coreRegistry->registry('store_action') == 'edit' && $codeBase && !$model->isReadOnly()) {
+                $this->messageManager->addNotice($codeBase);
+            }
+
+            $this->_initAction()->_addContent(
+                $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Store\Edit')
+            );
+            $this->_view->renderLayout();
+        } else {
+            $this->messageManager->addError($notExists);
+            $this->_redirect('adminhtml/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditWebsite.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditWebsite.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa375b2df52935b68059f6a95c9581cc7ba3da15
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/EditWebsite.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class EditWebsite extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_coreRegistry->register('store_type', 'website');
+        $this->_forward('editStore');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f446c0228501c13f7bb30b0bb1bc4c99793014c6
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Stores'));
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewGroup.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..093fe0799bee898712a94da50e96be9236babdc5
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewGroup.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class NewGroup extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_coreRegistry->register('store_type', 'group');
+        $this->_forward('newStore');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewStore.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..15e460caad4727c12cda5200dbf52422ac8191c1
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewStore.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class NewStore extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_coreRegistry->registry('store_type')) {
+            $this->_coreRegistry->register('store_type', 'store');
+        }
+        $this->_coreRegistry->register('store_action', 'add');
+        $this->_forward('editStore');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewWebsite.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewWebsite.php
new file mode 100644
index 0000000000000000000000000000000000000000..d091c7cf092d329058a2d5d2a456eb3f45981f21
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/NewWebsite.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class NewWebsite extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_coreRegistry->register('store_type', 'website');
+        $this->_forward('newStore');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..c379532f889bcefa38b90640459a60247d87819e
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Store/Save.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Store;
+
+class Save extends \Magento\Backend\Controller\Adminhtml\System\Store
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->isPost() && ($postData = $this->getRequest()->getPost())) {
+            if (empty($postData['store_type']) || empty($postData['store_action'])) {
+                $this->_redirect('adminhtml/*/');
+                return;
+            }
+
+            try {
+                switch ($postData['store_type']) {
+                    case 'website':
+                        $postData['website']['name'] = $this->filterManager->removeTags($postData['website']['name']);
+                        $websiteModel = $this->_objectManager->create('Magento\Store\Model\Website');
+                        if ($postData['website']['website_id']) {
+                            $websiteModel->load($postData['website']['website_id']);
+                        }
+                        $websiteModel->setData($postData['website']);
+                        if ($postData['website']['website_id'] == '') {
+                            $websiteModel->setId(null);
+                        }
+
+                        $websiteModel->save();
+                        $this->messageManager->addSuccess(__('The website has been saved.'));
+                        break;
+
+                    case 'group':
+                        $postData['group']['name'] = $this->filterManager->removeTags($postData['group']['name']);
+                        $groupModel = $this->_objectManager->create('Magento\Store\Model\Group');
+                        if ($postData['group']['group_id']) {
+                            $groupModel->load($postData['group']['group_id']);
+                        }
+                        $groupModel->setData($postData['group']);
+                        if ($postData['group']['group_id'] == '') {
+                            $groupModel->setId(null);
+                        }
+
+                        $groupModel->save();
+
+                        $this->_eventManager->dispatch('store_group_save', array('group' => $groupModel));
+
+                        $this->messageManager->addSuccess(__('The store has been saved.'));
+                        break;
+
+                    case 'store':
+                        $eventName = 'store_edit';
+                        $storeModel = $this->_objectManager->create('Magento\Store\Model\Store');
+                        $postData['store']['name'] = $this->filterManager->removeTags($postData['store']['name']);
+                        if ($postData['store']['store_id']) {
+                            $storeModel->load($postData['store']['store_id']);
+                        }
+                        $storeModel->setData($postData['store']);
+                        if ($postData['store']['store_id'] == '') {
+                            $storeModel->setId(null);
+                            $eventName = 'store_add';
+                        }
+                        $groupModel = $this->_objectManager->create(
+                            'Magento\Store\Model\Group'
+                        )->load(
+                            $storeModel->getGroupId()
+                        );
+                        $storeModel->setWebsiteId($groupModel->getWebsiteId());
+                        $storeModel->save();
+
+                        $this->_objectManager->get('Magento\Store\Model\StoreManager')->reinitStores();
+
+                        $this->_eventManager->dispatch($eventName, array('store' => $storeModel));
+
+                        $this->messageManager->addSuccess(__('The store view has been saved'));
+                        break;
+                    default:
+                        $this->_redirect('adminhtml/*/');
+                        return;
+                }
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_getSession()->setPostData($postData);
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('An error occurred while saving. Please review the error log.')
+                );
+                $this->_getSession()->setPostData($postData);
+            }
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+            return;
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php
index 3c8a8e7e9d0c1ec6b57d398c6d84516bc08029a8..66401200364624967b9934df3fe452c2f0e0cf36 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable.php
@@ -86,146 +86,6 @@ class Variable extends Action
         return $variable;
     }
 
-    /**
-     * Index Action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Custom Variables'));
-
-        $this->_initLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * New Action (forward to edit action)
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit Action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $variable = $this->_initVariable();
-
-        $this->_title->add($variable->getId() ? $variable->getCode() : __('New Custom Variable'));
-
-        $this->_initLayout()->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Variable\Edit')
-        )->_addJs(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Framework\View\Element\Template',
-                '',
-                array('data' => array('template' => 'Magento_Backend::system/variable/js.phtml'))
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Validate Action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object(array('error' => false));
-        $variable = $this->_initVariable();
-        $variable->addData($this->getRequest()->getPost('variable'));
-        $result = $variable->validate();
-        if ($result !== true && is_string($result)) {
-            $this->messageManager->addError($result);
-            $this->_view->getLayout()->initMessages();
-            $response->setError(true);
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Save Action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $variable = $this->_initVariable();
-        $data = $this->getRequest()->getPost('variable');
-        $back = $this->getRequest()->getParam('back', false);
-        if ($data) {
-            $data['variable_id'] = $variable->getId();
-            $variable->setData($data);
-            try {
-                $variable->save();
-                $this->messageManager->addSuccess(__('You saved the custom variable.'));
-                if ($back) {
-                    $this->_redirect(
-                        'adminhtml/*/edit',
-                        array('_current' => true, 'variable_id' => $variable->getId())
-                    );
-                } else {
-                    $this->_redirect('adminhtml/*/', array());
-                }
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('adminhtml/*/edit', array('_current' => true));
-                return;
-            }
-        }
-        $this->_redirect('adminhtml/*/', array());
-        return;
-    }
-
-    /**
-     * Delete Action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $variable = $this->_initVariable();
-        if ($variable->getId()) {
-            try {
-                $variable->delete();
-                $this->messageManager->addSuccess(__('You deleted the customer.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('adminhtml/*/edit', array('_current' => true));
-                return;
-            }
-        }
-        $this->_redirect('adminhtml/*/', array());
-        return;
-    }
-
-    /**
-     * WYSIWYG Plugin Action
-     *
-     * @return void
-     */
-    public function wysiwygPluginAction()
-    {
-        $customVariables = $this->_objectManager->create('Magento\Core\Model\Variable')->getVariablesOptionArray(true);
-        $storeContactVariabls = $this->_objectManager->create(
-            'Magento\Email\Model\Source\Variables'
-        )->toOptionArray(
-            true
-        );
-        $variables = array($storeContactVariabls, $customVariables);
-        $this->getResponse()->representJson(\Zend_Json::encode($variables));
-    }
-
     /**
      * Check current user permission
      *
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Delete.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..444ae5234735b8cb51d5a4e630ad2e25b28a330c
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Delete.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class Delete extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * Delete Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $variable = $this->_initVariable();
+        if ($variable->getId()) {
+            try {
+                $variable->delete();
+                $this->messageManager->addSuccess(__('You deleted the custom variable.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('adminhtml/*/edit', array('_current' => true));
+                return;
+            }
+        }
+        $this->_redirect('adminhtml/*/', array());
+        return;
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/ProductTaxClass.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Edit.php
similarity index 57%
rename from app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/ProductTaxClass.php
rename to app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Edit.php
index 24e8f85fc46d1dcf1c509cee1f23aad9bd3a4c30..e6f2f64279a8bdfed582f74d7b1e30646f8c3db8 100644
--- a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/ProductTaxClass.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Edit.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Product Tax Class option array
  *
  * Magento
  *
@@ -23,32 +22,30 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Tax\Model\Resource\Rule\Grid\Options;
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
 
-class ProductTaxClass implements \Magento\Framework\Option\ArrayInterface
+class Edit extends \Magento\Backend\Controller\Adminhtml\System\Variable
 {
     /**
-     * @var \Magento\Tax\Model\Resource\TaxClass\CollectionFactory
-     */
-    protected $_collectionFactory;
-
-    /**
-     * @param \Magento\Tax\Model\Resource\TaxClass\CollectionFactory $collectionFactory
-     */
-    public function __construct(\Magento\Tax\Model\Resource\TaxClass\CollectionFactory $collectionFactory)
-    {
-        $this->_collectionFactory = $collectionFactory;
-    }
-
-    /**
-     * Return Product Tax Class array
+     * Edit Action
      *
-     * @return array
+     * @return void
      */
-    public function toOptionArray()
+    public function execute()
     {
-        return $this->_collectionFactory->create()->setClassTypeFilter(
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
-        )->toOptionHash();
+        $variable = $this->_initVariable();
+
+        $this->_title->add($variable->getId() ? $variable->getCode() : __('New Custom Variable'));
+
+        $this->_initLayout()->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Backend\Block\System\Variable\Edit')
+        )->_addJs(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Framework\View\Element\Template',
+                '',
+                array('data' => array('template' => 'Magento_Backend::system/variable/js.phtml'))
+            )
+        );
+        $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..25942e3ff388c2b595fdc086331998a3e0e210eb
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * Index Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Custom Variables'));
+
+        $this->_initLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/NewAction.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..640d0042d2a44888a45bb16d2753a8a051454f06
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class NewAction extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * New Action (forward to edit action)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..843511c4cf642826be64dcc74bd7a20b7309e777
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Save.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class Save extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * Save Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $variable = $this->_initVariable();
+        $data = $this->getRequest()->getPost('variable');
+        $back = $this->getRequest()->getParam('back', false);
+        if ($data) {
+            $data['variable_id'] = $variable->getId();
+            $variable->setData($data);
+            try {
+                $variable->save();
+                $this->messageManager->addSuccess(__('You saved the custom variable.'));
+                if ($back) {
+                    $this->_redirect(
+                        'adminhtml/*/edit',
+                        array('_current' => true, 'variable_id' => $variable->getId())
+                    );
+                } else {
+                    $this->_redirect('adminhtml/*/', array());
+                }
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('adminhtml/*/edit', array('_current' => true));
+                return;
+            }
+        }
+        $this->_redirect('adminhtml/*/', array());
+        return;
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Validate.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..61515a7dc1a349db9440b59860ffa79bb3240749
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/Validate.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class Validate extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * Validate Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object(array('error' => false));
+        $variable = $this->_initVariable();
+        $variable->addData($this->getRequest()->getPost('variable'));
+        $result = $variable->validate();
+        if ($result !== true && is_string($result)) {
+            $this->messageManager->addError($result);
+            $this->_view->getLayout()->initMessages();
+            $response->setError(true);
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/WysiwygPlugin.php b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/WysiwygPlugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..69498fb1847a4b1f3a1ab2a6a044abb80df3b744
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/System/Variable/WysiwygPlugin.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\System\Variable;
+
+class WysiwygPlugin extends \Magento\Backend\Controller\Adminhtml\System\Variable
+{
+    /**
+     * WYSIWYG Plugin Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customVariables = $this->_objectManager->create('Magento\Core\Model\Variable')->getVariablesOptionArray(true);
+        $storeContactVariabls = $this->_objectManager->create(
+            'Magento\Email\Model\Source\Variables'
+        )->toOptionArray(
+            true
+        );
+        $variables = array($storeContactVariabls, $customVariables);
+        $this->getResponse()->representJson(\Zend_Json::encode($variables));
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
index 95615ccb376e48502ff48270becd3ff5d685babf..f6a4c537e37d03d1ded164b86f659f9c0633aee7 100644
--- a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite.php
@@ -26,518 +26,33 @@ namespace Magento\Backend\Controller\Adminhtml;
 use Magento\Backend\App\Action;
 use Magento\Catalog\Model\Category;
 use Magento\Catalog\Model\Product;
-use Magento\Framework\Model\Exception;
 
 /**
  * URL rewrite adminhtml controller
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ *
+ * @author      Magento Core Team <core@magentocommerce.com>
  */
 class Urlrewrite extends Action
 {
-    /**
-     * Default id mode key
-     */
-    const ID_MODE = 'id';
-
-    /**
-     * Product mode key
-     */
-    const PRODUCT_MODE = 'product';
-
-    /**
-     * Category mode key
-     */
-    const CATEGORY_MODE = 'category';
-
-    /**
-     * CMS mode key
-     */
-    const CMS_PAGE_MODE = 'cms_page';
-
     /**
      * @var Product
      */
-    protected $product;
+    protected $_product;
 
     /**
      * @var Category
      */
-    protected $category;
+    protected $_category;
 
     /**
      * @var \Magento\Cms\Model\Page
      */
-    protected $cmsPage;
+    protected $_cmsPage;
 
     /**
      * @var \Magento\UrlRewrite\Model\UrlRewrite
      */
-    protected $urlRewrite;
-
-    /**
-     * @var \Magento\Catalog\Model\ProductFactory
-     */
-    protected $productFactory;
-
-    /**
-     * @var \Magento\Backend\Block\Urlrewrite\Selector
-     */
-    protected $rewriteSelector;
-
-    /**
-     * @var \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree
-     */
-    protected $categoryTree;
-
-    /**
-     * @var \Magento\UrlRewrite\Helper\UrlRewrite
-     */
-    protected $rewriteHelper;
-
-    /**
-     * @var \Magento\Cms\Model\Page\UrlrewriteFactory
-     */
-    protected $cmsRewriteFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\CategoryFactory
-     */
-    protected $categoryFactory;
-
-    /**
-     * @var \Magento\UrlRewrite\Model\UrlRewriteFactory
-     */
-    protected $urlRewriteFactory;
-
-    /**
-     * @var \Magento\Cms\Model\PageFactory
-     */
-    protected $pageFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Url
-     */
-    protected $catalogUrl;
-
-    /**
-     * @var \Magento\Catalog\Model\Resource\UrlFactory
-     */
-    protected $catalogUrlFactory;
-
-    /**
-     * @param Action\Context $context
-     * @param \Magento\Catalog\Model\ProductFactory $productFactory
-     * @param \Magento\Backend\Block\Urlrewrite\Selector $rewriteSelector
-     * @param \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree $categoryTree
-     * @param \Magento\UrlRewrite\Helper\UrlRewrite $rewriteHelper
-     * @param \Magento\Cms\Model\Page\UrlrewriteFactory $cmsRewriteFactory
-     * @param \Magento\Catalog\Model\CategoryFactory $categoryFactory
-     * @param \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory
-     * @param \Magento\Cms\Model\PageFactory $pageFactory
-     * @param \Magento\Catalog\Model\Url $catalogUrl
-     * @param \Magento\Catalog\Model\Resource\UrlFactory $catalogUrlFactory
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Catalog\Model\ProductFactory $productFactory,
-        \Magento\Backend\Block\Urlrewrite\Selector $rewriteSelector,
-        \Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree $categoryTree,
-        \Magento\UrlRewrite\Helper\UrlRewrite $rewriteHelper,
-        \Magento\Cms\Model\Page\UrlrewriteFactory $cmsRewriteFactory,
-        \Magento\Catalog\Model\CategoryFactory $categoryFactory,
-        \Magento\UrlRewrite\Model\UrlRewriteFactory $urlRewriteFactory,
-        \Magento\Cms\Model\PageFactory $pageFactory,
-        \Magento\Catalog\Model\Url $catalogUrl,
-        \Magento\Catalog\Model\Resource\UrlFactory $catalogUrlFactory
-    ) {
-        $this->productFactory = $productFactory;
-        $this->rewriteSelector = $rewriteSelector;
-        $this->categoryTree = $categoryTree;
-        $this->rewriteHelper = $rewriteHelper;
-        $this->cmsRewriteFactory = $cmsRewriteFactory;
-        $this->categoryFactory = $categoryFactory;
-        $this->urlRewriteFactory = $urlRewriteFactory;
-        $this->pageFactory = $pageFactory;
-        $this->catalogUrl = $catalogUrl;
-        $this->catalogUrlFactory = $catalogUrlFactory;
-        parent::__construct($context);
-    }
-
-
-    /**
-     * Show URL rewrites index page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('URL Redirects'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Show urlrewrite edit/create page
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('URL Redirects'));
-        $this->_title->add(__('[New/Edit] URL Redirect'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
-
-        $mode = $this->getMode();
-
-        switch ($mode) {
-            case self::PRODUCT_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit',
-                    '',
-                    array(
-                        'data' => array(
-                            'category' => $this->getCategory(),
-                            'product' => $this->getProduct(),
-                            'is_category_mode' => $this->getRequest()->has('category'),
-                            'url_rewrite' => $this->getUrlRewrite()
-                        )
-                    )
-                );
-                break;
-            case self::CATEGORY_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit',
-                    '',
-                    array(
-                        'data' => array('category' => $this->getCategory(), 'url_rewrite' => $this->getUrlRewrite())
-                    )
-                );
-                break;
-            case self::CMS_PAGE_MODE:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit',
-                    '',
-                    array(
-                        'data' => array('cms_page' => $this->getCmsPage(), 'url_rewrite' => $this->getUrlRewrite())
-                    )
-                );
-                break;
-            case self::ID_MODE:
-            default:
-                $editBlock = $this->_view->getLayout()->createBlock(
-                    'Magento\Backend\Block\Urlrewrite\Edit',
-                    '',
-                    array('data' => array('url_rewrite' => $this->getUrlRewrite()))
-                );
-                break;
-        }
-
-        $this->_addContent($editBlock);
-        if (in_array($mode, array(self::PRODUCT_MODE, self::CATEGORY_MODE))) {
-            $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get current mode
-     *
-     * @return string
-     */
-    protected function getMode()
-    {
-        if ($this->getProduct()->getId() || $this->getRequest()->has('product')) {
-            $mode = self::PRODUCT_MODE;
-        } elseif ($this->getCategory()->getId() || $this->getRequest()->has('category')) {
-            $mode = self::CATEGORY_MODE;
-        } elseif ($this->getCmsPage()->getId() || $this->getRequest()->has('cms_page')) {
-            $mode = self::CMS_PAGE_MODE;
-        } elseif ($this->getRequest()->has('id')) {
-            $mode = self::ID_MODE;
-        } else {
-            $mode = $this->rewriteSelector->getDefaultMode();
-        }
-        return $mode;
-    }
-
-    /**
-     * Ajax products grid action
-     *
-     * @return void
-     */
-    public function productGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * Ajax categories tree loader action
-     *
-     * @return void
-     */
-    public function categoriesJsonAction()
-    {
-        $categoryId = $this->getRequest()->getParam('id', null);
-        $this->getResponse()->setBody($this->categoryTree->getTreeArray($categoryId, true, 1));
-    }
-
-    /**
-     * Ajax CMS pages grid action
-     *
-     * @return void
-     */
-    public function cmsPageGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Cms\Page\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * Urlrewrite save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            try {
-                // set basic urlrewrite data
-                /** @var $model \Magento\UrlRewrite\Model\UrlRewrite */
-                $model = $this->getUrlRewrite();
-
-                // Validate request path
-                $requestPath = $this->getRequest()->getParam('request_path');
-                $this->rewriteHelper->validateRequestPath($requestPath);
-
-                // Proceed and save request
-                $model->setIdPath($this->getRequest()->getParam('id_path'))
-                    ->setTargetPath($this->getRequest()->getParam('target_path'))
-                    ->setOptions($this->getRequest()->getParam('options'))
-                    ->setDescription($this->getRequest()->getParam('description'))
-                    ->setRequestPath($requestPath);
-
-                if (!$model->getId()) {
-                    $model->setIsSystem(0);
-                }
-                if (!$model->getIsSystem()) {
-                    $model->setStoreId($this->getRequest()->getParam('store_id', 0));
-                }
-
-                $this->onUrlRewriteSaveBefore($model);
-
-                // save and redirect
-                $model->save();
-
-                $this->onUrlRewriteSaveAfter($model);
-
-                $this->messageManager->addSuccess(__('The URL Rewrite has been saved.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_session->setUrlrewriteData($data);
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.'));
-                $this->_session->setUrlrewriteData($data);
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
-    /**
-     * Call before save urlrewrite handlers
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function onUrlRewriteSaveBefore($model)
-    {
-        $this->handleCatalogUrlRewrite($model);
-        $this->handleCmsPageUrlRewrite($model);
-    }
-
-    /**
-     * Call after save urlrewrite handlers
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function onUrlRewriteSaveAfter($model)
-    {
-        $this->handleCmsPageUrlRewriteSave($model);
-    }
-
-    /**
-     * Override urlrewrite data, basing on current category and product
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     * @throws Exception
-     */
-    protected function handleCatalogUrlRewrite($model)
-    {
-        $product = $this->getInitializedProduct($model);
-        $category = $this->getInitializedCategory($model);
-
-        if ($product || $category) {
-            $idPath = $this->catalogUrl->generatePath('id', $product, $category);
-            $model->setIdPath($idPath);
-
-            // if redirect specified try to find friendly URL
-            $generateTarget = true;
-            if ($this->rewriteHelper->hasRedirectOptions($model)) {
-                /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
-                $rewriteResource = $this->catalogUrlFactory->create();
-                /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-                $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
-                if (!$rewrite) {
-                    if ($product) {
-                        throw new Exception(
-                            __('Chosen product does not associated with the chosen store or category.')
-                        );
-                    } else {
-                        throw new Exception(__('Chosen category does not associated with the chosen store.'));
-                    }
-                } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
-                    $model->setTargetPath($rewrite->getRequestPath());
-                    $generateTarget = false;
-                }
-            }
-            if ($generateTarget) {
-                $model->setTargetPath($this->catalogUrl->generatePath('target', $product, $category));
-            }
-        }
-    }
-
-    /**
-     * Get product instance applicable for generatePath
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return Product|null
-     */
-    protected function getInitializedProduct($model)
-    {
-        /** @var $product Product */
-        $product = $this->getProduct();
-        if ($product->getId()) {
-            $model->setProductId($product->getId());
-        } else {
-            $product = null;
-        }
-
-        return $product;
-    }
-
-    /**
-     * Get category instance applicable for generatePath
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return Category|null
-     */
-    protected function getInitializedCategory($model)
-    {
-        /** @var $category Category */
-        $category = $this->getCategory();
-        if ($category->getId()) {
-            $model->setCategoryId($category->getId());
-        } else {
-            $category = null;
-        }
-        return $category;
-    }
-
-    /**
-     * Override URL rewrite data, basing on current CMS page
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function handleCmsPageUrlRewrite($model)
-    {
-        /** @var $cmsPage \Magento\Cms\Model\Page */
-        $cmsPage = $this->getCmsPage();
-        if (!$cmsPage->getId()) {
-            return;
-        }
-
-        /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsPageUrlRewrite = $this->cmsRewriteFactory->create();
-        $idPath = $cmsPageUrlRewrite->generateIdPath($cmsPage);
-        $model->setIdPath($idPath);
-
-        // if redirect specified try to find friendly URL
-        $generateTarget = true;
-        if ($model->getId() && $this->rewriteHelper->hasRedirectOptions($model)) {
-            /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
-            $rewriteResource = $this->catalogUrlFactory->create();
-            /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
-            $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
-            if (!$rewrite) {
-                throw new Exception(__('Chosen cms page does not associated with the chosen store.'));
-            } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
-                $model->setTargetPath($rewrite->getRequestPath());
-                $generateTarget = false;
-            }
-        }
-
-        if ($generateTarget) {
-            $model->setTargetPath($cmsPageUrlRewrite->generateTargetPath($cmsPage));
-        }
-    }
-
-    /**
-     * Save CMS page URL rewrite additional information
-     *
-     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
-     * @return void
-     */
-    protected function handleCmsPageUrlRewriteSave($model)
-    {
-        /** @var $cmsPage \Magento\Cms\Model\Page */
-        $cmsPage = $this->getCmsPage();
-        if (!$cmsPage->getId()) {
-            return;
-        }
-
-        /** @var $cmsRewrite \Magento\Cms\Model\Page\Urlrewrite */
-        $cmsRewrite = $this->cmsRewriteFactory->create();
-        $cmsRewrite->load($model->getId(), 'url_rewrite_id');
-        if (!$cmsRewrite->getId()) {
-            $cmsRewrite->setUrlRewriteId($model->getId());
-            $cmsRewrite->setCmsPageId($cmsPage->getId());
-            $cmsRewrite->save();
-        }
-    }
-
-    /**
-     * URL rewrite delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        if ($this->getUrlRewrite()->getId()) {
-            try {
-                $this->getUrlRewrite()->delete();
-                $this->messageManager->addSuccess(__('The URL Rewrite has been deleted.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while deleting URL Rewrite.'));
-                $this->_redirect('adminhtml/*/edit/', array('id' => $this->getUrlRewrite()->getId()));
-                return;
-            }
-        }
-        $this->_redirect('adminhtml/*/');
-    }
+    protected $_urlRewrite;
 
     /**
      * Check whether this contoller is allowed in admin permissions
@@ -554,21 +69,21 @@ class Urlrewrite extends Action
      *
      * @return Category
      */
-    protected function getCategory()
+    protected function _getCategory()
     {
-        if (!$this->category) {
-            $this->category = $this->categoryFactory->create();
-            $categoryId = (int) $this->getRequest()->getParam('category', 0);
+        if (!$this->_category) {
+            $this->_category = $this->_objectManager->create('Magento\Catalog\Model\Category');
+            $categoryId = (int)$this->getRequest()->getParam('category', 0);
 
-            if (!$categoryId && $this->getUrlRewrite()->getId()) {
-                $categoryId = $this->getUrlRewrite()->getCategoryId();
+            if (!$categoryId && $this->_getUrlRewrite()->getId()) {
+                $categoryId = $this->_getUrlRewrite()->getCategoryId();
             }
 
             if ($categoryId) {
-                $this->category->load($categoryId);
+                $this->_category->load($categoryId);
             }
         }
-        return $this->category;
+        return $this->_category;
     }
 
     /**
@@ -576,21 +91,21 @@ class Urlrewrite extends Action
      *
      * @return Product
      */
-    protected function getProduct()
+    protected function _getProduct()
     {
-        if (!$this->product) {
-            $this->product = $this->productFactory->create();
-            $productId = (int) $this->getRequest()->getParam('product', 0);
+        if (!$this->_product) {
+            $this->_product = $this->_objectManager->create('Magento\Catalog\Model\Product');
+            $productId = (int)$this->getRequest()->getParam('product', 0);
 
-            if (!$productId && $this->getUrlRewrite()->getId()) {
-                $productId = $this->getUrlRewrite()->getProductId();
+            if (!$productId && $this->_getUrlRewrite()->getId()) {
+                $productId = $this->_getUrlRewrite()->getProductId();
             }
 
             if ($productId) {
-                $this->product->load($productId);
+                $this->_product->load($productId);
             }
         }
-        return $this->product;
+        return $this->_product;
     }
 
     /**
@@ -598,25 +113,25 @@ class Urlrewrite extends Action
      *
      * @return \Magento\Cms\Model\Page
      */
-    protected function getCmsPage()
+    protected function _getCmsPage()
     {
-        if (!$this->cmsPage) {
-            $this->cmsPage = $this->pageFactory->create();
-            $cmsPageId = (int) $this->getRequest()->getParam('cms_page', 0);
+        if (!$this->_cmsPage) {
+            $this->_cmsPage = $this->_objectManager->create('Magento\Cms\Model\Page');
+            $cmsPageId = (int)$this->getRequest()->getParam('cms_page', 0);
 
-            if (!$cmsPageId && $this->getUrlRewrite()->getId()) {
-                $urlRewriteId = $this->getUrlRewrite()->getId();
+            if (!$cmsPageId && $this->_getUrlRewrite()->getId()) {
+                $urlRewriteId = $this->_getUrlRewrite()->getId();
                 /** @var $cmsUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
-                $cmsUrlRewrite = $this->cmsRewriteFactory->create();
+                $cmsUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
                 $cmsUrlRewrite->load($urlRewriteId, 'url_rewrite_id');
                 $cmsPageId = $cmsUrlRewrite->getCmsPageId();
             }
 
             if ($cmsPageId) {
-                $this->cmsPage->load($cmsPageId);
+                $this->_cmsPage->load($cmsPageId);
             }
         }
-        return $this->cmsPage;
+        return $this->_cmsPage;
     }
 
     /**
@@ -624,16 +139,16 @@ class Urlrewrite extends Action
      *
      * @return \Magento\UrlRewrite\Model\UrlRewrite
      */
-    protected function getUrlRewrite()
+    protected function _getUrlRewrite()
     {
-        if (!$this->urlRewrite) {
-            $this->urlRewrite = $this->urlRewriteFactory->create();
+        if (!$this->_urlRewrite) {
+            $this->_urlRewrite = $this->_objectManager->create('Magento\UrlRewrite\Model\UrlRewrite');
 
-            $urlRewriteId = (int) $this->getRequest()->getParam('id', 0);
+            $urlRewriteId = (int)$this->getRequest()->getParam('id', 0);
             if ($urlRewriteId) {
-                $this->urlRewrite->load((int) $this->getRequest()->getParam('id', 0));
+                $this->_urlRewrite->load((int)$this->getRequest()->getParam('id', 0));
             }
         }
-        return $this->urlRewrite;
+        return $this->_urlRewrite;
     }
 }
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..d1531fba2ffa30ad4052900406aa75f5281d8683
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CategoriesJson.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class CategoriesJson extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * Ajax categories tree loader action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $categoryId = $this->getRequest()->getParam('id', null);
+        $this->getResponse()->representJson(
+            $this->_objectManager->get(
+                'Magento\Backend\Block\Urlrewrite\Catalog\Category\Tree'
+            )->getTreeArray(
+                $categoryId,
+                true,
+                1
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..445db1ab97e98db5c39e9d4f56607f719718bfb4
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/CmsPageGrid.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class CmsPageGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * Ajax CMS pages grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Cms\Page\Grid')->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..612cd4f40b8a3b6aa4d66d1010aa20b16d015024
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Delete.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class Delete extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * URL rewrite delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getUrlRewrite()->getId()) {
+            try {
+                $this->_getUrlRewrite()->delete();
+                $this->messageManager->addSuccess(__('The URL Rewrite has been deleted.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while deleting URL Rewrite.'));
+                $this->_redirect('adminhtml/*/edit/', array('id' => $this->_getUrlRewrite()->getId()));
+                return;
+            }
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9feb97f13e8fd79bd052bc1c96c7a4cc86b718f
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Edit.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class Edit extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    const ID_MODE = 'id';
+
+    const PRODUCT_MODE = 'product';
+
+    const CATEGORY_MODE = 'category';
+
+    const CMS_PAGE_MODE = 'cms_page';
+
+    /**
+     * Get current mode
+     *
+     * @return string
+     */
+    protected function _getMode()
+    {
+        if ($this->_getProduct()->getId() || $this->getRequest()->has('product')) {
+            $mode = self::PRODUCT_MODE;
+        } elseif ($this->_getCategory()->getId() || $this->getRequest()->has('category')) {
+            $mode = self::CATEGORY_MODE;
+        } elseif ($this->_getCmsPage()->getId() || $this->getRequest()->has('cms_page')) {
+            $mode = self::CMS_PAGE_MODE;
+        } elseif ($this->getRequest()->has('id')) {
+            $mode = self::ID_MODE;
+        } else {
+            $mode = $this->_objectManager->get('Magento\Backend\Block\Urlrewrite\Selector')->getDefaultMode();
+        }
+        return $mode;
+    }
+
+    /**
+     * Show urlrewrite edit/create page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('URL Redirects'));
+        $this->_title->add(__('[New/Edit] URL Redirect'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
+
+        $mode = $this->_getMode();
+
+        switch ($mode) {
+            case self::PRODUCT_MODE:
+                $editBlock = $this->_view->getLayout()->createBlock(
+                    'Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit',
+                    '',
+                    array(
+                        'data' => array(
+                            'category' => $this->_getCategory(),
+                            'product' => $this->_getProduct(),
+                            'is_category_mode' => $this->getRequest()->has('category'),
+                            'url_rewrite' => $this->_getUrlRewrite()
+                        )
+                    )
+                );
+                break;
+            case self::CATEGORY_MODE:
+                $editBlock = $this->_view->getLayout()->createBlock(
+                    'Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit',
+                    '',
+                    array(
+                        'data' => array('category' => $this->_getCategory(), 'url_rewrite' => $this->_getUrlRewrite())
+                    )
+                );
+                break;
+            case self::CMS_PAGE_MODE:
+                $editBlock = $this->_view->getLayout()->createBlock(
+                    'Magento\Backend\Block\Urlrewrite\Cms\Page\Edit',
+                    '',
+                    array(
+                        'data' => array('cms_page' => $this->_getCmsPage(), 'url_rewrite' => $this->_getUrlRewrite())
+                    )
+                );
+                break;
+            case self::ID_MODE:
+            default:
+                $editBlock = $this->_view->getLayout()->createBlock(
+                    'Magento\Backend\Block\Urlrewrite\Edit',
+                    '',
+                    array('data' => array('url_rewrite' => $this->_getUrlRewrite()))
+                );
+                break;
+        }
+
+        $this->_addContent($editBlock);
+        if (in_array($mode, array(self::PRODUCT_MODE, self::CATEGORY_MODE))) {
+            $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..76de37ae37ac42c5efec82c28e5839df07084c55
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class Index extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * Show URL rewrites index page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('URL Redirects'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_urlrewrite');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5e0f8579c5b4cbde407f0a7a5e0893e8d8cefd0
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/ProductGrid.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+class ProductGrid extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * Ajax products grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock('Magento\Backend\Block\Urlrewrite\Catalog\Product\Grid')->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ac8b5ac9d18404896f6aa78f0be4ab1b324c7db
--- /dev/null
+++ b/app/code/Magento/Backend/Controller/Adminhtml/Urlrewrite/Save.php
@@ -0,0 +1,262 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backend\Controller\Adminhtml\Urlrewrite;
+
+use Magento\Catalog\Model\Category;
+use Magento\Catalog\Model\Product;
+use Magento\Framework\Model\Exception;
+
+class Save extends \Magento\Backend\Controller\Adminhtml\Urlrewrite
+{
+    /**
+     * Call before save urlrewrite handlers
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     */
+    protected function _onUrlRewriteSaveBefore($model)
+    {
+        $this->_handleCatalogUrlRewrite($model);
+        $this->_handleCmsPageUrlRewrite($model);
+    }
+
+    /**
+     * Call after save urlrewrite handlers
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     */
+    protected function _onUrlRewriteSaveAfter($model)
+    {
+        $this->_handleCmsPageUrlRewriteSave($model);
+    }
+
+    /**
+     * Override urlrewrite data, basing on current category and product
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     * @throws Exception
+     */
+    protected function _handleCatalogUrlRewrite($model)
+    {
+        $product = $this->_getInitializedProduct($model);
+        $category = $this->_getInitializedCategory($model);
+
+        if ($product || $category) {
+            /** @var $catalogUrlModel \Magento\Catalog\Model\Url */
+            $catalogUrlModel = $this->_objectManager->get('Magento\Catalog\Model\Url');
+            $idPath = $catalogUrlModel->generatePath('id', $product, $category);
+            $model->setIdPath($idPath);
+
+            // if redirect specified try to find friendly URL
+            $generateTarget = true;
+            if ($this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->hasRedirectOptions($model)) {
+                /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
+                $rewriteResource = $this->_objectManager->create('Magento\Catalog\Model\Resource\Url');
+                /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
+                $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
+                if (!$rewrite) {
+                    if ($product) {
+                        throw new Exception(
+                            __('Chosen product does not associated with the chosen store or category.')
+                        );
+                    } else {
+                        throw new Exception(__('Chosen category does not associated with the chosen store.'));
+                    }
+                } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
+                    $model->setTargetPath($rewrite->getRequestPath());
+                    $generateTarget = false;
+                }
+            }
+            if ($generateTarget) {
+                $model->setTargetPath($catalogUrlModel->generatePath('target', $product, $category));
+            }
+        }
+    }
+
+    /**
+     * Get product instance applicable for generatePath
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return Product|null
+     */
+    protected function _getInitializedProduct($model)
+    {
+        /** @var $product Product */
+        $product = $this->_getProduct();
+        if ($product->getId()) {
+            $model->setProductId($product->getId());
+        } else {
+            $product = null;
+        }
+
+        return $product;
+    }
+
+    /**
+     * Override URL rewrite data, basing on current CMS page
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    protected function _handleCmsPageUrlRewrite($model)
+    {
+        /** @var $cmsPage \Magento\Cms\Model\Page */
+        $cmsPage = $this->_getCmsPage();
+        if (!$cmsPage->getId()) {
+            return;
+        }
+
+        /** @var $cmsPageUrlRewrite \Magento\Cms\Model\Page\Urlrewrite */
+        $cmsPageUrlRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
+        $idPath = $cmsPageUrlRewrite->generateIdPath($cmsPage);
+        $model->setIdPath($idPath);
+
+        // if redirect specified try to find friendly URL
+        $generateTarget = true;
+        if ($model->getId()
+            && $this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->hasRedirectOptions($model)
+        ) {
+            /** @var $rewriteResource \Magento\Catalog\Model\Resource\Url */
+            $rewriteResource = $this->_objectManager->create('Magento\Catalog\Model\Resource\Url');
+            /** @var $rewrite \Magento\UrlRewrite\Model\UrlRewrite */
+            $rewrite = $rewriteResource->getRewriteByIdPath($idPath, $model->getStoreId());
+            if (!$rewrite) {
+                throw new Exception(__('Chosen cms page does not associated with the chosen store.'));
+            } elseif ($rewrite->getId() && $rewrite->getId() != $model->getId()) {
+                $model->setTargetPath($rewrite->getRequestPath());
+                $generateTarget = false;
+            }
+        }
+
+        if ($generateTarget) {
+            $model->setTargetPath($cmsPageUrlRewrite->generateTargetPath($cmsPage));
+        }
+    }
+
+    /**
+     * Save CMS page URL rewrite additional information
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return void
+     */
+    protected function _handleCmsPageUrlRewriteSave($model)
+    {
+        /** @var $cmsPage \Magento\Cms\Model\Page */
+        $cmsPage = $this->_getCmsPage();
+        if (!$cmsPage->getId()) {
+            return;
+        }
+
+        /** @var $cmsRewrite \Magento\Cms\Model\Page\Urlrewrite */
+        $cmsRewrite = $this->_objectManager->create('Magento\Cms\Model\Page\Urlrewrite');
+        $cmsRewrite->load($model->getId(), 'url_rewrite_id');
+        if (!$cmsRewrite->getId()) {
+            $cmsRewrite->setUrlRewriteId($model->getId());
+            $cmsRewrite->setCmsPageId($cmsPage->getId());
+            $cmsRewrite->save();
+        }
+    }
+
+    /**
+     * Get category instance applicable for generatePath
+     *
+     * @param \Magento\UrlRewrite\Model\UrlRewrite $model
+     * @return Category|null
+     */
+    protected function _getInitializedCategory($model)
+    {
+        /** @var $category Category */
+        $category = $this->_getCategory();
+        if ($category->getId()) {
+            $model->setCategoryId($category->getId());
+        } else {
+            $category = null;
+        }
+        return $category;
+    }
+
+    /**
+     * Urlrewrite save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($data = $this->getRequest()->getPost()) {
+            /** @var $session \Magento\Backend\Model\Session */
+            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+            try {
+                // set basic urlrewrite data
+                /** @var $model \Magento\UrlRewrite\Model\UrlRewrite */
+                $model = $this->_getUrlRewrite();
+
+                // Validate request path
+                $requestPath = $this->getRequest()->getParam('request_path');
+                $this->_objectManager->get('Magento\UrlRewrite\Helper\UrlRewrite')->validateRequestPath($requestPath);
+
+                // Proceed and save request
+                $model->setIdPath(
+                    $this->getRequest()->getParam('id_path')
+                )->setTargetPath(
+                    $this->getRequest()->getParam('target_path')
+                )->setOptions(
+                    $this->getRequest()->getParam('options')
+                )->setDescription(
+                    $this->getRequest()->getParam('description')
+                )->setRequestPath(
+                    $requestPath
+                );
+
+                if (!$model->getId()) {
+                    $model->setIsSystem(0);
+                }
+                if (!$model->getIsSystem()) {
+                    $model->setStoreId($this->getRequest()->getParam('store_id', 0));
+                }
+
+                $this->_onUrlRewriteSaveBefore($model);
+
+                // save and redirect
+                $model->save();
+
+                $this->_onUrlRewriteSaveAfter($model);
+
+                $this->messageManager->addSuccess(__('The URL Rewrite has been saved.'));
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $session->setUrlrewriteData($data);
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while saving URL Rewrite.'));
+                $session->setUrlrewriteData($data);
+            }
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/Backend/Model/View.php b/app/code/Magento/Backend/Model/View.php
index c37ca412a36c0b7f65785892b117482b0b18c869..b9c9f1bb9350289a62a4e65a9d56c217777f7cec 100644
--- a/app/code/Magento/Backend/Model/View.php
+++ b/app/code/Magento/Backend/Model/View.php
@@ -57,9 +57,9 @@ class View extends \Magento\Framework\App\View
     /**
      * {@inheritdoc}
      */
-    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
+    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true, $addActionHandles = true)
     {
-        parent::loadLayout($handles, false, $generateXml);
+        parent::loadLayout($handles, false, $generateXml, $addActionHandles);
         $this->_aclFilter->filterAclNodes($this->getLayout()->getNode());
         if ($generateBlocks) {
             $this->generateLayoutBlocks();
diff --git a/app/code/Magento/Backend/etc/adminhtml/di.xml b/app/code/Magento/Backend/etc/adminhtml/di.xml
index 0c75baed88bae33ca8cba1958fa7313288635e44..781422eebdd061e738f84ac79865db01e0d67b56 100644
--- a/app/code/Magento/Backend/etc/adminhtml/di.xml
+++ b/app/code/Magento/Backend/etc/adminhtml/di.xml
@@ -62,7 +62,7 @@
         <arguments>
             <argument name="routerList" xsi:type="array">
                 <item name="admin" xsi:type="array">
-                    <item name="class" xsi:type="string">Magento\Backend\App\Router\DefaultRouter</item>
+                    <item name="class" xsi:type="string">Magento\Backend\App\Router</item>
                     <item name="disable" xsi:type="boolean">false</item>
                     <item name="sortOrder" xsi:type="string">10</item>
                 </item>
diff --git a/app/code/Magento/Backend/etc/di.xml b/app/code/Magento/Backend/etc/di.xml
index 331df7123659feb25f09bc653c35cc9b487dd920..adff60676d1e66666528b6727fedfc75d5cf37a9 100644
--- a/app/code/Magento/Backend/etc/di.xml
+++ b/app/code/Magento/Backend/etc/di.xml
@@ -33,6 +33,8 @@
     <preference for="Magento\Adminhtml\Helper\Data" type="Magento\Backend\Helper\Data" />
     <preference for="Magento\Backend\App\ConfigInterface" type="Magento\Backend\App\Config" />
     <preference for="Magento\Backend\Model\UrlInterface" type="Magento\Backend\Model\Url" />
+    <preference for="Magento\Backend\Block\Widget\Button\ToolbarInterface" type="Magento\Backend\Block\Widget\Button\Toolbar" />
+    <type name="Magento\Backend\Block\Widget\Button\ButtonList" shared="false" />
     <type name="Magento\Framework\App\AreaList">
         <arguments>
             <argument name="areas" xsi:type="array">
@@ -43,7 +45,7 @@
             </argument>
         </arguments>
     </type>
-    <type name="Magento\Backend\App\Router\DefaultRouter">
+    <type name="Magento\Backend\App\Router">
         <arguments>
             <argument name="routerId" xsi:type="string">admin</argument>
         </arguments>
@@ -136,7 +138,7 @@
             <argument name="identifier" xsi:type="string">Magento_Adminhtml::all</argument>
         </arguments>
     </type>
-    <type name="Magento\Backend\Controller\Adminhtml\Index">
+    <type name="Magento\Backend\Controller\Adminhtml\Index\GlobalSearch">
         <arguments>
             <argument name="searchModules" xsi:type="array">
                 <item name="products" xsi:type="array">
diff --git a/app/code/Magento/Backend/i18n/de_DE.csv b/app/code/Magento/Backend/i18n/de_DE.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/de_DE.csv
+++ b/app/code/Magento/Backend/i18n/de_DE.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/en_US.csv b/app/code/Magento/Backend/i18n/en_US.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/en_US.csv
+++ b/app/code/Magento/Backend/i18n/en_US.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/es_ES.csv b/app/code/Magento/Backend/i18n/es_ES.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/es_ES.csv
+++ b/app/code/Magento/Backend/i18n/es_ES.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/fr_FR.csv b/app/code/Magento/Backend/i18n/fr_FR.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/fr_FR.csv
+++ b/app/code/Magento/Backend/i18n/fr_FR.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/nl_NL.csv b/app/code/Magento/Backend/i18n/nl_NL.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/nl_NL.csv
+++ b/app/code/Magento/Backend/i18n/nl_NL.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/pt_BR.csv b/app/code/Magento/Backend/i18n/pt_BR.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/pt_BR.csv
+++ b/app/code/Magento/Backend/i18n/pt_BR.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backend/i18n/zh_CN.csv b/app/code/Magento/Backend/i18n/zh_CN.csv
index ba811a0ba34c10a77cf85f728b6c1ecd117d4960..42d4d718f5dfa71c79dcdd8e0cccedce5711d1f9 100644
--- a/app/code/Magento/Backend/i18n/zh_CN.csv
+++ b/app/code/Magento/Backend/i18n/zh_CN.csv
@@ -272,7 +272,7 @@ Synchronizing...,Synchronizing...
 "We couldn't create a backup right now. Please try again later.","We couldn't create a backup right now. Please try again later."
 "Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1.","Deleting a %1 will not delete the information associated with the %1 (e.g. categories, products, etc.), but the %1 will not be able to be restored. It is suggested that you create a database backup before deleting the %1."
 "You saved the custom variable.","You saved the custom variable."
-"You deleted the customer.","You deleted the customer."
+"You deleted the custom variable.","You deleted the custom variable."
 "URL Redirects","URL Redirects"
 "[New/Edit] URL Redirect","[New/Edit] URL Redirect"
 "The URL Rewrite has been saved.","The URL Rewrite has been saved."
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index.php
index 0b12997b80c78c7aaaa33f9e94601fe943faba7b..f0a921c5ac7053ab526973e5b4afd3c51cc93aae 100644
--- a/app/code/Magento/Backup/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index.php
@@ -81,355 +81,6 @@ class Index extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Backup list action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Backups'));
-
-        if ($this->getRequest()->getParam('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Backup::system_tools_backup');
-        $this->_addBreadcrumb(__('System'), __('System'));
-        $this->_addBreadcrumb(__('Tools'), __('Tools'));
-        $this->_addBreadcrumb(__('Backups'), __('Backup'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Backup list action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->renderLayot(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create backup action
-     *
-     * @return void|\Magento\Backend\App\Action
-     */
-    public function createAction()
-    {
-        if (!$this->getRequest()->isAjax()) {
-            return $this->_redirect('*/*/index');
-        }
-
-        $response = new \Magento\Framework\Object();
-
-        /**
-         * @var \Magento\Backup\Helper\Data $helper
-         */
-        $helper = $this->_objectManager->get('Magento\Backup\Helper\Data');
-
-        try {
-            $type = $this->getRequest()->getParam('type');
-
-            if ($type == \Magento\Framework\Backup\Factory::TYPE_SYSTEM_SNAPSHOT && $this->getRequest()->getParam(
-                'exclude_media'
-            )
-            ) {
-                $type = \Magento\Framework\Backup\Factory::TYPE_SNAPSHOT_WITHOUT_MEDIA;
-            }
-
-            $backupManager = $this->_backupFactory->create(
-                $type
-            )->setBackupExtension(
-                $helper->getExtensionByType($type)
-            )->setTime(
-                time()
-            )->setBackupsDir(
-                $helper->getBackupsDir()
-            );
-
-            $backupManager->setName($this->getRequest()->getParam('backup_name'));
-
-            $this->_coreRegistry->register('backup_manager', $backupManager);
-
-            if ($this->getRequest()->getParam('maintenance_mode')) {
-                if (!$this->maintenanceMode->turnOn()) {
-                    $response->setError(
-                        __(
-                            'You need more permissions to activate maintenance mode right now.'
-                        ) . ' ' . __(
-                            'To continue with the backup, you need to either deselect ' .
-                            '"Put store on the maintenance mode" or update your permissions.'
-                        )
-                    );
-                    $backupManager->setErrorMessage(
-                        __('Something went wrong putting your store into maintenance mode.')
-                    );
-                    return $this->getResponse()->representJson($response->toJson());
-                }
-            }
-
-            if ($type != \Magento\Framework\Backup\Factory::TYPE_DB) {
-                $backupManager->setRootDir(
-                    $this->_objectManager->get('Magento\Framework\App\Filesystem')->getPath()
-                )->addIgnorePaths(
-                    $helper->getBackupIgnorePaths()
-                );
-            }
-
-            $successMessage = $helper->getCreateSuccessMessageByType($type);
-
-            $backupManager->create();
-
-            $this->messageManager->addSuccess($successMessage);
-
-            $response->setRedirectUrl($this->getUrl('*/*/index'));
-        } catch (\Magento\Framework\Backup\Exception\NotEnoughFreeSpace $e) {
-            $errorMessage = __('You need more free space to create a backup.');
-        } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
-            $errorMessage = __('You need more permissions to create a backup.');
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
-            $errorMessage = __('Something went wrong creating the backup.');
-        }
-
-        if (!empty($errorMessage)) {
-            $response->setError($errorMessage);
-            $backupManager->setErrorMessage($errorMessage);
-        }
-
-        if ($this->getRequest()->getParam('maintenance_mode')) {
-            $this->maintenanceMode->turnOff();
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Download backup action
-     *
-     * @return void|\Magento\Backend\App\Action
-     */
-    public function downloadAction()
-    {
-        /* @var $backup \Magento\Backup\Model\Backup */
-        $backup = $this->_backupModelFactory->create(
-            $this->getRequest()->getParam('time'),
-            $this->getRequest()->getParam('type')
-        );
-
-        if (!$backup->getTime() || !$backup->exists()) {
-            return $this->_redirect('backup/*');
-        }
-
-        $fileName = $this->_objectManager->get('Magento\Backup\Helper\Data')->generateBackupDownloadName($backup);
-
-        $response = $this->_fileFactory->create(
-            $fileName,
-            null,
-            \Magento\Framework\App\Filesystem::VAR_DIR,
-            'application/octet-stream',
-            $backup->getSize()
-        );
-
-        $response->sendHeaders();
-
-        $backup->output();
-        exit;
-    }
-
-    /**
-     * Rollback Action
-     *
-     * @return void|\Magento\Backend\App\Action
-     */
-    public function rollbackAction()
-    {
-        if (!$this->_objectManager->get('Magento\Backup\Helper\Data')->isRollbackAllowed()) {
-            $this->_forward('denied');
-        }
-
-        if (!$this->getRequest()->isAjax()) {
-            return $this->_redirect('*/*/index');
-        }
-
-        $helper = $this->_objectManager->get('Magento\Backup\Helper\Data');
-        $response = new \Magento\Framework\Object();
-
-        try {
-            /* @var $backup \Magento\Backup\Model\Backup */
-            $backup = $this->_backupModelFactory->create(
-                $this->getRequest()->getParam('time'),
-                $this->getRequest()->getParam('type')
-            );
-
-            if (!$backup->getTime() || !$backup->exists()) {
-                return $this->_redirect('backup/*');
-            }
-
-            if (!$backup->getTime()) {
-                throw new \Magento\Framework\Backup\Exception\CantLoadSnapshot();
-            }
-
-            $type = $backup->getType();
-
-            $backupManager = $this->_backupFactory->create(
-                $type
-            )->setBackupExtension(
-                $helper->getExtensionByType($type)
-            )->setTime(
-                $backup->getTime()
-            )->setBackupsDir(
-                $helper->getBackupsDir()
-            )->setName(
-                $backup->getName(),
-                false
-            )->setResourceModel(
-                $this->_objectManager->create('Magento\Backup\Model\Resource\Db')
-            );
-
-            $this->_coreRegistry->register('backup_manager', $backupManager);
-
-            $passwordValid = $this->_objectManager->create(
-                'Magento\Backup\Model\Backup'
-            )->validateUserPassword(
-                $this->getRequest()->getParam('password')
-            );
-
-            if (!$passwordValid) {
-                $response->setError(__('Please correct the password.'));
-                $backupManager->setErrorMessage(__('Please correct the password.'));
-                $this->getResponse()->representJson($response->toJson());
-            }
-
-            if ($this->getRequest()->getParam('maintenance_mode')) {
-                if (!$this->maintenanceMode->turnOn()) {
-                    $response->setError(
-                        __(
-                            'You need more permissions to activate maintenance mode right now.'
-                        ) . ' ' . __(
-                            'To continue with the rollback, you need to either deselect ' .
-                            '"Put store on the maintenance mode" or update your permissions.'
-                        )
-                    );
-                    $backupManager->setErrorMessage(
-                        __('Something went wrong putting your store into maintenance mode.')
-                    );
-                    return $this->getResponse()->representJson($response->toJson());
-                }
-            }
-
-            if ($type != \Magento\Framework\Backup\Factory::TYPE_DB) {
-
-                $backupManager->setRootDir(
-                    $this->_objectManager->get('Magento\Framework\App\Filesystem')->getPath()
-                )->addIgnorePaths(
-                    $helper->getRollbackIgnorePaths()
-                );
-
-                if ($this->getRequest()->getParam('use_ftp', false)) {
-                    $backupManager->setUseFtp(
-                        $this->getRequest()->getParam('ftp_host', ''),
-                        $this->getRequest()->getParam('ftp_user', ''),
-                        $this->getRequest()->getParam('ftp_pass', ''),
-                        $this->getRequest()->getParam('ftp_path', '')
-                    );
-                }
-            }
-
-            $backupManager->rollback();
-
-            $helper->invalidateCache()->invalidateIndexer();
-
-            $adminSession = $this->_getSession();
-            $adminSession->destroy();
-
-            $response->setRedirectUrl($this->getUrl('*'));
-        } catch (\Magento\Framework\Backup\Exception\CantLoadSnapshot $e) {
-            $errorMsg = __('The backup file was not found.');
-        } catch (\Magento\Framework\Backup\Exception\FtpConnectionFailed $e) {
-            $errorMsg = __('We couldn\'t connect to the FTP.');
-        } catch (\Magento\Framework\Backup\Exception\FtpValidationFailed $e) {
-            $errorMsg = __('Failed to validate FTP');
-        } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
-            $errorMsg = __('Not enough permissions to perform rollback.');
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
-            $errorMsg = __('Failed to rollback');
-        }
-
-        if (!empty($errorMsg)) {
-            $response->setError($errorMsg);
-            $backupManager->setErrorMessage($errorMsg);
-        }
-
-        if ($this->getRequest()->getParam('maintenance_mode')) {
-            $this->maintenanceMode->turnOff();
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Delete backups mass action
-     *
-     * @return \Magento\Backend\App\Action
-     */
-    public function massDeleteAction()
-    {
-        $backupIds = $this->getRequest()->getParam('ids', array());
-
-        if (!is_array($backupIds) || !count($backupIds)) {
-            return $this->_redirect('backup/*/index');
-        }
-
-        $resultData = new \Magento\Framework\Object();
-        $resultData->setIsSuccess(false);
-        $resultData->setDeleteResult(array());
-        $this->_coreRegistry->register('backup_manager', $resultData);
-
-        $deleteFailMessage = __('We couldn\'t delete one or more backups.');
-
-        try {
-            $allBackupsDeleted = true;
-
-            foreach ($backupIds as $id) {
-                list($time, $type) = explode('_', $id);
-                $backupModel = $this->_backupModelFactory->create($time, $type)->deleteFile();
-
-                if ($backupModel->exists()) {
-                    $allBackupsDeleted = false;
-                    $result = __('failed');
-                } else {
-                    $result = __('successful');
-                }
-
-                $resultData->setDeleteResult(
-                    array_merge($resultData->getDeleteResult(), array($backupModel->getFileName() . ' ' . $result))
-                );
-            }
-
-            $resultData->setIsSuccess(true);
-            if ($allBackupsDeleted) {
-                $this->messageManager->addSuccess(__('The selected backup(s) has been deleted.'));
-            } else {
-                throw new \Exception($deleteFailMessage);
-            }
-        } catch (\Exception $e) {
-            $resultData->setIsSuccess(false);
-            $this->messageManager->addError($deleteFailMessage);
-        }
-
-        return $this->_redirect('backup/*/index');
-    }
-
     /**
      * Check Permissions for all actions
      *
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
new file mode 100644
index 0000000000000000000000000000000000000000..5472af57770aa52187577e89812a7fbcde039ac9
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Create.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class Create extends \Magento\Backup\Controller\Adminhtml\Index
+{
+    /**
+     * Create backup action
+     *
+     * @return void|\Magento\Backend\App\Action
+     */
+    public function execute()
+    {
+        if (!$this->getRequest()->isAjax()) {
+            return $this->_redirect('*/*/index');
+        }
+
+        $response = new \Magento\Framework\Object();
+
+        /**
+         * @var \Magento\Backup\Helper\Data $helper
+         */
+        $helper = $this->_objectManager->get('Magento\Backup\Helper\Data');
+
+        try {
+            $type = $this->getRequest()->getParam('type');
+
+            if ($type == \Magento\Framework\Backup\Factory::TYPE_SYSTEM_SNAPSHOT && $this->getRequest()->getParam(
+                'exclude_media'
+            )
+            ) {
+                $type = \Magento\Framework\Backup\Factory::TYPE_SNAPSHOT_WITHOUT_MEDIA;
+            }
+
+            $backupManager = $this->_backupFactory->create(
+                $type
+            )->setBackupExtension(
+                $helper->getExtensionByType($type)
+            )->setTime(
+                time()
+            )->setBackupsDir(
+                $helper->getBackupsDir()
+            );
+
+            $backupManager->setName($this->getRequest()->getParam('backup_name'));
+
+            $this->_coreRegistry->register('backup_manager', $backupManager);
+
+            if ($this->getRequest()->getParam('maintenance_mode')) {
+                if (!$this->maintenanceMode->turnOn()) {
+                    $response->setError(
+                        __(
+                            'You need more permissions to activate maintenance mode right now.'
+                        ) . ' ' . __(
+                            'To continue with the backup, you need to either deselect ' .
+                            '"Put store on the maintenance mode" or update your permissions.'
+                        )
+                    );
+                    $backupManager->setErrorMessage(
+                        __("Something went wrong putting your store into maintenance mode.")
+                    );
+                    return $this->getResponse()->representJson($response->toJson());
+                }
+            }
+
+            if ($type != \Magento\Framework\Backup\Factory::TYPE_DB) {
+                $backupManager->setRootDir(
+                    $this->_objectManager->get('Magento\Framework\App\Filesystem')->getPath()
+                )->addIgnorePaths(
+                    $helper->getBackupIgnorePaths()
+                );
+            }
+
+            $successMessage = $helper->getCreateSuccessMessageByType($type);
+
+            $backupManager->create();
+
+            $this->messageManager->addSuccess($successMessage);
+
+            $response->setRedirectUrl($this->getUrl('*/*/index'));
+        } catch (\Magento\Framework\Backup\Exception\NotEnoughFreeSpace $e) {
+            $errorMessage = __('You need more free space to create a backup.');
+        } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $errorMessage = __('You need more permissions to create a backup.');
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $errorMessage = __('Something went wrong creating the backup.');
+        }
+
+        if (!empty($errorMessage)) {
+            $response->setError($errorMessage);
+            $backupManager->setErrorMessage($errorMessage);
+        }
+
+        if ($this->getRequest()->getParam('maintenance_mode')) {
+            $this->maintenanceMode->turnOff();
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a41d6c42b332fc0c2bff3795330070d82b0966d
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Download.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class Download extends \Magento\Backup\Controller\Adminhtml\Index
+{
+
+    /**
+     * Download backup action
+     *
+     * @return void|\Magento\Backend\App\Action
+     */
+    public function execute()
+    {
+        /* @var $backup \Magento\Backup\Model\Backup */
+        $backup = $this->_backupModelFactory->create(
+            $this->getRequest()->getParam('time'),
+            $this->getRequest()->getParam('type')
+        );
+
+        if (!$backup->getTime() || !$backup->exists()) {
+            return $this->_redirect('backup/*');
+        }
+
+        $fileName = $this->_objectManager->get('Magento\Backup\Helper\Data')->generateBackupDownloadName($backup);
+
+        $response = $this->_fileFactory->create(
+            $fileName,
+            null,
+            \Magento\Framework\App\Filesystem::VAR_DIR,
+            'application/octet-stream',
+            $backup->getSize()
+        );
+
+        $response->sendHeaders();
+
+        $backup->output();
+        exit;
+    }
+}
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Grid.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..6995c69970c0dd7b45d685c293c46f6fa05de8f8
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class Grid extends \Magento\Backup\Controller\Adminhtml\Index
+{
+    /**
+     * Backup list action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->renderLayot(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Index.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab64455954fe1315f1d2582a7ca654e1b4ae2f10
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Index.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class Index extends \Magento\Backup\Controller\Adminhtml\Index
+{
+    /**
+     * Backup list action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Backups'));
+
+        if ($this->getRequest()->getParam('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Backup::system_tools_backup');
+        $this->_addBreadcrumb(__('System'), __('System'));
+        $this->_addBreadcrumb(__('Tools'), __('Tools'));
+        $this->_addBreadcrumb(__('Backups'), __('Backup'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/MassDelete.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..161c197dc9d96968381ea780bd8658237ce8a429
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/MassDelete.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class MassDelete extends \Magento\Backup\Controller\Adminhtml\Index
+{
+    /**
+     * Delete backups mass action
+     *
+     * @return \Magento\Backend\App\Action
+     */
+    public function execute()
+    {
+        $backupIds = $this->getRequest()->getParam('ids', array());
+
+        if (!is_array($backupIds) || !count($backupIds)) {
+            return $this->_redirect('backup/*/index');
+        }
+
+        $resultData = new \Magento\Framework\Object();
+        $resultData->setIsSuccess(false);
+        $resultData->setDeleteResult(array());
+        $this->_coreRegistry->register('backup_manager', $resultData);
+
+        $deleteFailMessage = __('We couldn\'t delete one or more backups.');
+
+        try {
+            $allBackupsDeleted = true;
+
+            foreach ($backupIds as $id) {
+                list($time, $type) = explode('_', $id);
+                $backupModel = $this->_backupModelFactory->create($time, $type)->deleteFile();
+
+                if ($backupModel->exists()) {
+                    $allBackupsDeleted = false;
+                    $result = __('failed');
+                } else {
+                    $result = __('successful');
+                }
+
+                $resultData->setDeleteResult(
+                    array_merge($resultData->getDeleteResult(), array($backupModel->getFileName() . ' ' . $result))
+                );
+            }
+
+            $resultData->setIsSuccess(true);
+            if ($allBackupsDeleted) {
+                $this->messageManager->addSuccess(__('The selected backup(s) has been deleted.'));
+            } else {
+                throw new \Exception($deleteFailMessage);
+            }
+        } catch (\Exception $e) {
+            $resultData->setIsSuccess(false);
+            $this->messageManager->addError($deleteFailMessage);
+        }
+
+        return $this->_redirect('backup/*/index');
+    }
+}
diff --git a/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb0848da57ac66e3e64d6689202bc1b8f94a3d47
--- /dev/null
+++ b/app/code/Magento/Backup/Controller/Adminhtml/Index/Rollback.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Backup\Controller\Adminhtml\Index;
+
+class Rollback extends \Magento\Backup\Controller\Adminhtml\Index
+{
+    /**
+     * Rollback Action
+     *
+     * @return void|\Magento\Backend\App\Action
+     */
+    public function execute()
+    {
+        if (!$this->_objectManager->get('Magento\Backup\Helper\Data')->isRollbackAllowed()) {
+            $this->_forward('denied');
+        }
+
+        if (!$this->getRequest()->isAjax()) {
+            return $this->_redirect('*/*/index');
+        }
+
+        $helper = $this->_objectManager->get('Magento\Backup\Helper\Data');
+        $response = new \Magento\Framework\Object();
+
+        try {
+            /* @var $backup \Magento\Backup\Model\Backup */
+            $backup = $this->_backupModelFactory->create(
+                $this->getRequest()->getParam('time'),
+                $this->getRequest()->getParam('type')
+            );
+
+            if (!$backup->getTime() || !$backup->exists()) {
+                return $this->_redirect('backup/*');
+            }
+
+            if (!$backup->getTime()) {
+                throw new \Magento\Framework\Backup\Exception\CantLoadSnapshot();
+            }
+
+            $type = $backup->getType();
+
+            $backupManager = $this->_backupFactory->create(
+                $type
+            )->setBackupExtension(
+                $helper->getExtensionByType($type)
+            )->setTime(
+                $backup->getTime()
+            )->setBackupsDir(
+                $helper->getBackupsDir()
+            )->setName(
+                $backup->getName(),
+                false
+            )->setResourceModel(
+                $this->_objectManager->create('Magento\Backup\Model\Resource\Db')
+            );
+
+            $this->_coreRegistry->register('backup_manager', $backupManager);
+
+            $passwordValid = $this->_objectManager->create(
+                'Magento\Backup\Model\Backup'
+            )->validateUserPassword(
+                $this->getRequest()->getParam('password')
+            );
+
+            if (!$passwordValid) {
+                $response->setError(__('Please correct the password.'));
+                $backupManager->setErrorMessage(__('Please correct the password.'));
+                return $this->getResponse()->representJson($response->toJson());
+            }
+
+            if ($this->getRequest()->getParam('maintenance_mode')) {
+                if (!$this->maintenanceMode->turnOn()) {
+                    $response->setError(
+                        __(
+                            'You need more permissions to activate maintenance mode right now.'
+                        ) . ' ' . __(
+                            'To continue with the rollback, you need to either deselect ' .
+                            '"Put store on the maintenance mode" or update your permissions.'
+                        )
+                    );
+                    $backupManager->setErrorMessage(
+                        __('Something went wrong putting your store into maintenance mode.')
+                    );
+                    return $this->getResponse()->representJson($response->toJson());
+                }
+            }
+
+            if ($type != \Magento\Framework\Backup\Factory::TYPE_DB) {
+
+                $backupManager->setRootDir(
+                    $this->_objectManager->get('Magento\Framework\App\Filesystem')->getPath()
+                )->addIgnorePaths(
+                    $helper->getRollbackIgnorePaths()
+                );
+
+                if ($this->getRequest()->getParam('use_ftp', false)) {
+                    $backupManager->setUseFtp(
+                        $this->getRequest()->getParam('ftp_host', ''),
+                        $this->getRequest()->getParam('ftp_user', ''),
+                        $this->getRequest()->getParam('ftp_pass', ''),
+                        $this->getRequest()->getParam('ftp_path', '')
+                    );
+                }
+            }
+
+            $backupManager->rollback();
+
+            $helper->invalidateCache()->invalidateIndexer();
+
+            $adminSession = $this->_getSession();
+            $adminSession->destroy();
+
+            $response->setRedirectUrl($this->getUrl('*'));
+        } catch (\Magento\Framework\Backup\Exception\CantLoadSnapshot $e) {
+            $errorMsg = __('The backup file was not found.');
+        } catch (\Magento\Framework\Backup\Exception\FtpConnectionFailed $e) {
+            $errorMsg = __('We couldn\'t connect to the FTP.');
+        } catch (\Magento\Framework\Backup\Exception\FtpValidationFailed $e) {
+            $errorMsg = __('Failed to validate FTP');
+        } catch (\Magento\Framework\Backup\Exception\NotEnoughPermissions $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $errorMsg = __('Not enough permissions to perform rollback.');
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->log($e->getMessage());
+            $errorMsg = __('Failed to rollback');
+        }
+
+        if (!empty($errorMsg)) {
+            $response->setError($errorMsg);
+            $backupManager->setErrorMessage($errorMsg);
+        }
+
+        if ($this->getRequest()->getParam('maintenance_mode')) {
+            $this->maintenanceMode->turnOff();
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Backup/etc/adminhtml/routes.xml b/app/code/Magento/Backup/etc/adminhtml/routes.xml
index 7d2605f49171a162821455380e3b548310cc79c3..94ed31ee440a32e69eded3a6b00c571948160850 100644
--- a/app/code/Magento/Backup/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Backup/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="backup" frontName="backup">
-            <module name="Magento_Backup_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_Backup" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/Backup/view/adminhtml/templates/backup/dialogs.phtml b/app/code/Magento/Backup/view/adminhtml/templates/backup/dialogs.phtml
index a3d7602ce28f93f5410c281f2319625a6e3f2989..200a88e3ec25762676fc7dd7f8918c2a54ac2476 100644
--- a/app/code/Magento/Backup/view/adminhtml/templates/backup/dialogs.phtml
+++ b/app/code/Magento/Backup/view/adminhtml/templates/backup/dialogs.phtml
@@ -71,7 +71,7 @@
                     <div class="form-list question">
 
                         <label for="backup_name" class="nobr"><?php echo __('Backup Name')?></label>
-                        <input type="text" name="backup_name" id="backup_name" class="validate-alphanum-with-spaces validate-length maximum-length-50" maxlength="50" />
+                        <input type="text" name="backup_name" id="backup_name" class="required-entry validate-alphanum-with-spaces validate-length maximum-length-50" maxlength="50" />
                         <div class="note"><?php echo __('Please use only letters (a-z or A-Z), numbers (0-9) or spaces in this field.'); ?></div>
 
                         <div class="maintenance-checkbox-container">
diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/Price.php b/app/code/Magento/Bundle/Block/Catalog/Product/Price.php
index bd6d82f44cdb4a4550812101d54d19103710a2bd..792c4dcd3571932b5e6efd34a5164b9d847a65ae 100644
--- a/app/code/Magento/Bundle/Block/Catalog/Product/Price.php
+++ b/app/code/Magento/Bundle/Block/Catalog/Product/Price.php
@@ -29,11 +29,6 @@ namespace Magento\Bundle\Block\Catalog\Product;
  */
 class Price extends \Magento\Catalog\Block\Product\Price
 {
-    /**
-     * @var \Magento\Tax\Model\Calculation
-     */
-    protected $_taxCalc;
-
     /**
      * @param \Magento\Framework\View\Element\Template\Context $context
      * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
@@ -43,7 +38,6 @@ class Price extends \Magento\Catalog\Block\Product\Price
      * @param \Magento\Framework\Stdlib\String $string
      * @param \Magento\Framework\Math\Random $mathRandom
      * @param \Magento\Checkout\Helper\Cart $cartHelper
-     * @param \Magento\Tax\Model\Calculation $taxCalc
      * @param array $data
      */
     public function __construct(
@@ -55,7 +49,6 @@ class Price extends \Magento\Catalog\Block\Product\Price
         \Magento\Framework\Stdlib\String $string,
         \Magento\Framework\Math\Random $mathRandom,
         \Magento\Checkout\Helper\Cart $cartHelper,
-        \Magento\Tax\Model\Calculation $taxCalc,
         array $data = array()
     ) {
         parent::__construct(
@@ -69,23 +62,6 @@ class Price extends \Magento\Catalog\Block\Product\Price
             $cartHelper,
             $data
         );
-        $this->_taxCalc = $taxCalc;
-    }
-
-    /**
-     * @return bool
-     */
-    public function isRatesGraterThenZero()
-    {
-        $request = $this->_taxCalc->getRateRequest(false, false, false);
-        $request->setProductClassId($this->getProduct()->getTaxClassId());
-        $defaultTax = $this->_taxCalc->getRate($request);
-
-        $request = $this->_taxCalc->getRateRequest();
-        $request->setProductClassId($this->getProduct()->getTaxClassId());
-        $currentTax = $this->_taxCalc->getRate($request);
-
-        return floatval($defaultTax) > 0 || floatval($currentTax) > 0;
     }
 
     /**
diff --git a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php
index 459d7e037df5e696aded92f5fe248809ad176c29..5db6ad5396e5f5f91e8556fa38702a7cba7804aa 100644
--- a/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php
+++ b/app/code/Magento/Bundle/Block/Catalog/Product/View/Type/Bundle/Option.php
@@ -58,7 +58,6 @@ class Option extends \Magento\Bundle\Block\Catalog\Product\Price
      * @param \Magento\Framework\Stdlib\String $string
      * @param \Magento\Framework\Math\Random $mathRandom
      * @param \Magento\Checkout\Helper\Cart $cartHelper
-     * @param \Magento\Tax\Model\Calculation $taxCalc
      * @param \Magento\Core\Helper\Data $coreHelper
      * @param array $data
      *
@@ -73,7 +72,6 @@ class Option extends \Magento\Bundle\Block\Catalog\Product\Price
         \Magento\Framework\Stdlib\String $string,
         \Magento\Framework\Math\Random $mathRandom,
         \Magento\Checkout\Helper\Cart $cartHelper,
-        \Magento\Tax\Model\Calculation $taxCalc,
         \Magento\Core\Helper\Data $coreHelper,
         array $data = array()
     ) {
@@ -87,7 +85,6 @@ class Option extends \Magento\Bundle\Block\Catalog\Product\Price
             $string,
             $mathRandom,
             $cartHelper,
-            $taxCalc,
             $data
         );
     }
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AddAttributeToTemplate.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AddAttributeToTemplate.php
new file mode 100644
index 0000000000000000000000000000000000000000..58386d80d1b8733fd06fa110a30236ee46455407
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AddAttributeToTemplate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Product\AddAttributeToTemplate
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsPriceGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsPriceGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..88195431d2378a2894bc9ce5b075cc59f6e9f499
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsPriceGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class AlertsPriceGrid extends \Magento\Catalog\Controller\Adminhtml\Product\AlertsPriceGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsStockGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsStockGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..dde800a44ad56dae6c2f075f9c8a2eeb49c52e1a
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/AlertsStockGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class AlertsStockGrid extends \Magento\Catalog\Controller\Adminhtml\Product\AlertsStockGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Categories.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Categories.php
new file mode 100644
index 0000000000000000000000000000000000000000..821b81e3266e8fbe86aa7486e92d322d89a56b0b
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Categories.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Categories extends \Magento\Catalog\Controller\Adminhtml\Product\Categories
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Crosssell.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Crosssell.php
new file mode 100644
index 0000000000000000000000000000000000000000..228bf07ff869300c98b6f60bd6b640ed5ee04804
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Crosssell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Crosssell extends \Magento\Catalog\Controller\Adminhtml\Product\Crosssell
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CrosssellGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CrosssellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5ce1b04cb4b98f9b17764502ec76ca73479f3f3
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CrosssellGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class CrosssellGrid extends \Magento\Catalog\Controller\Adminhtml\Product\CrosssellGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CustomOptions.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CustomOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6bc628bc3136d324d3d4790535a283f34c6292d
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/CustomOptions.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class CustomOptions extends \Magento\Catalog\Controller\Adminhtml\Product\CustomOptions
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Duplicate.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Duplicate.php
new file mode 100644
index 0000000000000000000000000000000000000000..42831871f6dddbdb26cafe608c1818b580dff2a9
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Duplicate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Duplicate extends \Magento\Catalog\Controller\Adminhtml\Product\Duplicate
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Edit.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..42fc906e9f4fe58fb1239e32565c6a133f19d6db
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Edit.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Edit
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Form.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..d82c277ea73ba60801be23b649ed827efc7a8959
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Form.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class Form extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper
+     */
+    protected $initializationHelper;
+
+    /**
+     * @param Action\Context $context
+     * @param Product\Builder $productBuilder
+     * @param Product\Initialization\Helper $iniitializationHelper
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        Product\Initialization\Helper $iniitializationHelper
+    ) {
+        $this->initializationHelper = $iniitializationHelper;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle',
+                'admin.product.bundle.items'
+            )->setProductId(
+                $product->getId()
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Grid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..ace3ea2a927954673e357cf5de0b989500876116
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Grid extends \Magento\Catalog\Controller\Adminhtml\Product\Grid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/GridOnly.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/GridOnly.php
new file mode 100644
index 0000000000000000000000000000000000000000..f22e5076d1291d9740ed8de304cee1460c6461b0
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/GridOnly.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class GridOnly extends \Magento\Catalog\Controller\Adminhtml\Product\GridOnly
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Index.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..01438a26ea27dc894955a24a7005cdeb9fe9748f
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Product\Index
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassDelete.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..46f4983104e0228abfdb1f0b63d0b644dd5e30bf
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassDelete.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product\MassDelete
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassStatus.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd38e4f9ac0358bb407f9c8c4d3b182c4f6b1acd
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/MassStatus.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product\MassStatus
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/NewAction.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..80b986e79b74c25ba11a02904fe1dd643b589866
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/NewAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product\NewAction
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Options.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Options.php
new file mode 100644
index 0000000000000000000000000000000000000000..49df745f8510cd9c35935fc40755fae6d3fec078
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Options.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Options extends \Magento\Catalog\Controller\Adminhtml\Product\Options
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/OptionsImportGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/OptionsImportGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..8cfa2eec726a801d1df75d3d7ccda3f1ec86767b
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/OptionsImportGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class OptionsImportGrid extends \Magento\Catalog\Controller\Adminhtml\Product\OptionsImportGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Related.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Related.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff303a6b510b4bf794925cb1a90803ade79df8a6
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Related.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Related extends \Magento\Catalog\Controller\Adminhtml\Product\Related
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/RelatedGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/RelatedGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..bde3b837e20ca080fa0294ab784d7040a5eb5a30
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/RelatedGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class RelatedGrid extends \Magento\Catalog\Controller\Adminhtml\Product\RelatedGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Save.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..82dac94a35b0f98f51664bc73648e1876e26e1a8
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Save.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Save
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/ShowUpdateResult.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..410550a5b349a8d12227721ead6b13f0c3a6941f
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/ShowUpdateResult.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class ShowUpdateResult extends \Magento\Catalog\Controller\Adminhtml\Product\ShowUpdateResult
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestAttributes.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestAttributes.php
new file mode 100644
index 0000000000000000000000000000000000000000..5074945012dc1ee22093e4acfd7b0721950d6d40
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestAttributes.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class SuggestAttributes extends \Magento\Catalog\Controller\Adminhtml\Product\SuggestAttributes
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestProductTemplates.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestProductTemplates.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cc890c504ee4ea5ad50817cdd2563a8cd40a773
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/SuggestProductTemplates.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class SuggestProductTemplates extends \Magento\Catalog\Controller\Adminhtml\Product\SuggestProductTemplates
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Upsell.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Upsell.php
new file mode 100644
index 0000000000000000000000000000000000000000..36a970ab71fa7aa780c6d27cdb1a10fc5454302e
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Upsell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Upsell extends \Magento\Catalog\Controller\Adminhtml\Product\Upsell
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/UpsellGrid.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/UpsellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6f20265411f3b3f6c805e751bd5b9ac53310475
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/UpsellGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class UpsellGrid extends \Magento\Catalog\Controller\Adminhtml\Product\UpsellGrid
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Validate.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb048bdb8734a8cf7332b3f241f59e13c271a842
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Validate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Validate
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Wysiwyg.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Wysiwyg.php
new file mode 100644
index 0000000000000000000000000000000000000000..f12483553725fdd5bc79de6dc5a6021332300f1a
--- /dev/null
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit/Wysiwyg.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product\Edit;
+
+class Wysiwyg extends \Magento\Catalog\Controller\Adminhtml\Product\Wysiwyg
+{
+}
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Grid.php
similarity index 69%
rename from app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit.php
rename to app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Grid.php
index 2be760f8b0c34560e15c43ac5a66ae6dbd2addea..a7c3ff14f63aff6fde21c55af6c0cd40a24d218b 100644
--- a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Product/Edit.php
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Grid.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,27 +22,21 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Bundle\Controller\Adminhtml\Bundle\Product;
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Selection;
 
-/**
- * Adminhtml bundle product edit
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
+class Grid extends \Magento\Backend\App\Action
 {
     /**
-     * @return void
+     * @return mixed
      */
-    public function formAction()
+    public function execute()
     {
-        $product = $this->_initProduct();
-        $this->getResponse()->setBody(
+        return $this->getResponse()->setBody(
             $this->_view->getLayout()->createBlock(
-                'Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle',
-                'admin.product.bundle.items'
-            )->setProductId(
-                $product->getId()
+                'Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid',
+                'adminhtml.catalog.product.edit.tab.bundle.option.search.grid'
+            )->setIndex(
+                $this->getRequest()->getParam('index')
             )->toHtml()
         );
     }
diff --git a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection.php b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Search.php
similarity index 64%
rename from app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection.php
rename to app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Search.php
index 18d4132e9846846d77de0a90757ea8c8850f9f52..1905a2ef499829065e55e37431d111a5a9301af4 100644
--- a/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection.php
+++ b/app/code/Magento/Bundle/Controller/Adminhtml/Bundle/Selection/Search.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,19 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Bundle\Controller\Adminhtml\Bundle;
+namespace Magento\Bundle\Controller\Adminhtml\Bundle\Selection;
 
-/**
- * Adminhtml selection grid controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Selection extends \Magento\Backend\App\Action
+class Search extends \Magento\Backend\App\Action
 {
     /**
      * @return mixed
      */
-    public function searchAction()
+    public function execute()
     {
         return $this->getResponse()->setBody(
             $this->_view->getLayout()->createBlock(
@@ -45,19 +41,4 @@ class Selection extends \Magento\Backend\App\Action
             )->toHtml()
         );
     }
-
-    /**
-     * @return mixed
-     */
-    public function gridAction()
-    {
-        return $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Bundle\Block\Adminhtml\Catalog\Product\Edit\Tab\Bundle\Option\Search\Grid',
-                'adminhtml.catalog.product.edit.tab.bundle.option.search.grid'
-            )->setIndex(
-                $this->getRequest()->getParam('index')
-            )->toHtml()
-        );
-    }
 }
diff --git a/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php b/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php
index 0578caaf9f782e54ef8d1c2065532b2ce37768da..70677b41a7f83fa035c6461c2d60194a43a38e0c 100644
--- a/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php
+++ b/app/code/Magento/Bundle/Pricing/Price/DiscountCalculator.php
@@ -40,7 +40,7 @@ class DiscountCalculator
      */
     public function calculateDiscount(Product $product, $value = null)
     {
-        if (!$value) {
+        if (is_null($value)) {
             $value = $product->getPriceInfo()->getPrice(FinalPrice::PRICE_CODE)->getValue();
         }
 
diff --git a/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php b/app/code/Magento/Captcha/Controller/Adminhtml/Refresh/Refresh.php
similarity index 80%
rename from app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php
rename to app/code/Magento/Captcha/Controller/Adminhtml/Refresh/Refresh.php
index 9c7622334aec94fbc037a81608542b279008a40a..f3abd379e2aaa945b7a7bb418bfdeb51978824ce 100644
--- a/app/code/Magento/Captcha/Controller/Adminhtml/Refresh.php
+++ b/app/code/Magento/Captcha/Controller/Adminhtml/Refresh/Refresh.php
@@ -1,5 +1,8 @@
 <?php
 /**
+ * Refreshes captcha and returns JSON encoded URL to image (AJAX action)
+ * Example: {'imgSrc': 'http://example.com/media/captcha/67842gh187612ngf8s.png'}
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,22 +24,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Captcha\Controller\Adminhtml;
+namespace Magento\Captcha\Controller\Adminhtml\Refresh;
 
-/**
- * Captcha controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
 class Refresh extends \Magento\Backend\App\Action
 {
     /**
-     * Refreshes captcha and returns JSON encoded URL to image (AJAX action)
-     * Example: {'imgSrc': 'http://example.com/media/captcha/67842gh187612ngf8s.png'}
-     *
-     * @return void
+     * {@inheritdoc}
      */
-    public function refreshAction()
+    public function execute()
     {
         $formId = $this->getRequest()->getPost('formId');
         $captchaModel = $this->_objectManager->get('Magento\Captcha\Helper\Data')->getCaptcha($formId);
diff --git a/app/code/Magento/Captcha/Controller/Refresh/Index.php b/app/code/Magento/Captcha/Controller/Refresh/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7390ed3fe2e4c45543133739ee795bc97a2ae033
--- /dev/null
+++ b/app/code/Magento/Captcha/Controller/Refresh/Index.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Refreshes captcha and returns JSON encoded URL to image (AJAX action)
+ * Example: {'imgSrc': 'http://example.com/media/captcha/67842gh187612ngf8s.png'}
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Captcha\Controller\Refresh;
+
+use Magento\Framework\App\Action\AbstractAction;
+use Magento\Framework\App\Action\Context;
+
+class Index extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var \Magento\Captcha\Helper\Data
+     */
+    protected $captchaHelper;
+
+    /**
+     * @param Context $context
+     * @param \Magento\Captcha\Helper\Data $captchaHelper
+     */
+    public function __construct(Context $context, \Magento\Captcha\Helper\Data $captchaHelper)
+    {
+        $this->captchaHelper;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $formId = $this->_request->getPost('formId');
+        $captchaModel = $this->captchaHelper->getCaptcha($formId);
+        $block = $this->_view->getLayout()->createBlock($captchaModel->getBlockName());
+        $block->setFormId($formId)->setIsAjax(true)->toHtml();
+        $this->_response->representJson(json_encode(array('imgSrc' => $captchaModel->getImgSrc())));
+        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+    }
+}
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit.php
index c976b7da2d23011f921ee95e87b19c27c30a8e4e..342bdba301b0245d78cd27b73958338b920cdb2a 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Category/Edit.php
@@ -45,8 +45,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml_category';
         $this->_mode = 'edit';
         parent::_construct();
-        $this->_removeButton('back');
-        $this->_removeButton('reset');
-        $this->_removeButton('save');
+        $this->buttonList->remove('back');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('save');
     }
 }
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product.php b/app/code/Magento/Catalog/Block/Adminhtml/Product.php
index ef162522cb8d86a1d5c1ec582670c716b0e14717..c472075aec32ce783094398d1abfbb23d6759311 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product.php
@@ -47,13 +47,13 @@ class Product extends \Magento\Backend\Block\Widget\Container
     protected $_productFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Catalog\Model\Product\TypeFactory $typeFactory
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Catalog\Model\Product\TypeFactory $typeFactory,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         array $data = array()
@@ -79,7 +79,7 @@ class Product extends \Magento\Backend\Block\Widget\Container
             'class_name' => 'Magento\Backend\Block\Widget\Button\SplitButton',
             'options' => $this->_getAddProductButtonOptions()
         );
-        $this->_addButton('add_new', $addButtonProps);
+        $this->buttonList->add('add_new', $addButtonProps);
 
         $this->setChild(
             'grid',
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit.php
index 5d230a2fbcaa3bac02ccaa80eaa3fd2e9f29f299..5e3a5c5814423bd35f222562698539b6d6e6b0ce 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Attribute/Edit.php
@@ -43,12 +43,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -67,19 +67,20 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         parent::_construct();
 
         if ($this->getRequest()->getParam('popup')) {
-            $this->_removeButton('back');
+            $this->buttonList->remove('back');
             if ($this->getRequest()->getParam('product_tab') != 'variations') {
-                $this->_addButton(
+                $this->addButton(
                     'save_in_new_set',
                     array(
                         'label' => __('Save in New Attribute Set'),
                         'class' => 'save',
                         'onclick' => 'saveAttributeInNewSet(\'' . __('Enter Name for New Attribute Set') . '\')'
-                    )
+                    ),
+                    100
                 );
             }
         } else {
-            $this->_addButton(
+            $this->addButton(
                 'save_and_edit_button',
                 array(
                     'label' => __('Save and Continue Edit'),
@@ -89,14 +90,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                             'button' => array('event' => 'saveAndContinueEdit', 'target' => '#edit_form')
                         )
                     )
-                ),
-                100
+                )
             );
         }
 
-        $this->_updateButton('save', 'label', __('Save Attribute'));
-        $this->_updateButton('save', 'class', 'save primary');
-        $this->_updateButton(
+        $this->buttonList->update('save', 'label', __('Save Attribute'));
+        $this->buttonList->update('save', 'class', 'save primary');
+        $this->buttonList->update(
             'save',
             'data_attribute',
             array('mage-init' => array('button' => array('event' => 'save', 'target' => '#edit_form')))
@@ -104,21 +104,21 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         $entityAttribute = $this->_coreRegistry->registry('entity_attribute');
         if (!$entityAttribute || !$entityAttribute->getIsUserDefined()) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         } else {
-            $this->_updateButton('delete', 'label', __('Delete Attribute'));
+            $this->buttonList->update('delete', 'label', __('Delete Attribute'));
         }
     }
 
     /**
      * {@inheritdoc}
      */
-    protected function _addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
     {
         if ($this->getRequest()->getParam('popup')) {
             $region = 'header';
         }
-        parent::_addButton($buttonId, $data, $level, $sortOrder, $region);
+        parent::addButton($buttonId, $data, $level, $sortOrder, $region);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Js.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Js.php
index 63cfce9eebc176b6e964ebf028c587954f14d52d..51891fbcac6044c8bf9a38a6c502f08e3b7f155c 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Js.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Js.php
@@ -21,8 +21,13 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Catalog\Block\Adminhtml\Product\Edit;
 
+use Magento\Customer\Helper\Session\CurrentCustomer;
+use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
+use Magento\Tax\Model\TaxClass\Source\Product as ProductTaxClassSource;
+
 class Js extends \Magento\Backend\Block\Template
 {
     /**
@@ -30,19 +35,55 @@ class Js extends \Magento\Backend\Block\Template
      *
      * @var \Magento\Framework\Registry
      */
-    protected $_coreRegistry = null;
+    protected $coreRegistry = null;
+
+    /**
+     * @var TaxCalculationServiceInterface
+     */
+    protected $calculationService;
+
+    /**
+     * @var ProductTaxClassSource
+     */
+    protected $productTaxClassSource;
+
+    /**
+     * Current customer
+     *
+     * @var CurrentCustomer
+     */
+    protected $currentCustomer;
+
+    /**
+     * Core data
+     *
+     * @var \Magento\Core\Helper\Data
+     */
+    protected $coreHelper;
 
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Registry $registry
+     * @param CurrentCustomer $currentCustomer
+     * @param \Magento\Core\Helper\Data $coreHelper
+     * @param TaxCalculationServiceInterface $calculationService
+     * @param ProductTaxClassSource $productTaxClassSource
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
         \Magento\Framework\Registry $registry,
+        CurrentCustomer $currentCustomer,
+        \Magento\Core\Helper\Data $coreHelper,
+        TaxCalculationServiceInterface $calculationService,
+        ProductTaxClassSource $productTaxClassSource,
         array $data = array()
     ) {
-        $this->_coreRegistry = $registry;
+        $this->coreRegistry = $registry;
+        $this->currentCustomer = $currentCustomer;
+        $this->coreHelper = $coreHelper;
+        $this->calculationService = $calculationService;
+        $this->productTaxClassSource = $productTaxClassSource;
         parent::__construct($context, $data);
     }
 
@@ -53,7 +94,7 @@ class Js extends \Magento\Backend\Block\Template
      */
     public function getProduct()
     {
-        return $this->_coreRegistry->registry('current_product');
+        return $this->coreRegistry->registry('current_product');
     }
 
     /**
@@ -69,4 +110,24 @@ class Js extends \Magento\Backend\Block\Template
         }
         return $this->_storeManager->getStore();
     }
+
+    /**
+     * Get all tax rates JSON for all product tax classes.
+     *
+     * @return string
+     */
+    public function getAllRatesByProductClassJson()
+    {
+        $result = array();
+        foreach ($this->productTaxClassSource->getAllOptions() as $productTaxClass) {
+            $taxClassId = $productTaxClass['value'];
+            $taxRate = $this->calculationService->getDefaultCalculatedRate(
+                $taxClassId,
+                $this->currentCustomer->getCustomerId(),
+                $this->getStore()->getId()
+            );
+            $result["value_{$taxClassId}"] = $taxRate;
+        }
+        return $this->coreHelper->jsonEncode($result);
+    }
 }
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Search/Edit.php b/app/code/Magento/Catalog/Block/Adminhtml/Search/Edit.php
index 877dcee2a63eae36cbf596c2d0faffad1ae04643..c2450add498f677e9402fa9f9d8af9397410eb01 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Search/Edit.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Search/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $coreRegistry;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -60,8 +60,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Search'));
-        $this->_updateButton('delete', 'label', __('Delete Search'));
+        $this->buttonList->update('save', 'label', __('Save Search'));
+        $this->buttonList->update('delete', 'label', __('Delete Search'));
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Block/Product/View.php b/app/code/Magento/Catalog/Block/Product/View.php
index 031273808fa6bf81a497a3e3829ca3fc637798ad..0922334fd41aeec981159d8b5869b622a7747977 100644
--- a/app/code/Magento/Catalog/Block/Product/View.php
+++ b/app/code/Magento/Catalog/Block/Product/View.php
@@ -24,6 +24,7 @@
 namespace Magento\Catalog\Block\Product;
 
 use Magento\Catalog\Model\Product;
+use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
 
 /**
  * Product View block
@@ -84,6 +85,16 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
      */
     protected $_localeFormat;
 
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var TaxCalculationServiceInterface
+     */
+    protected $taxCalculationService;
+
     /**
      * @param Context $context
      * @param \Magento\Core\Helper\Data $coreData
@@ -94,6 +105,8 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
      * @param \Magento\Catalog\Helper\Product $productHelper
      * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param TaxCalculationServiceInterface $taxCalculationService
      * @param array $data
      */
     public function __construct(
@@ -106,6 +119,8 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
         \Magento\Catalog\Helper\Product $productHelper,
         \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
+        \Magento\Customer\Model\Session $customerSession,
+        TaxCalculationServiceInterface $taxCalculationService,
         array $data = array()
     ) {
         $this->_productHelper = $productHelper;
@@ -116,6 +131,8 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
         $this->productTypeConfig = $productTypeConfig;
         $this->string = $string;
         $this->_localeFormat = $localeFormat;
+        $this->customerSession = $customerSession;
+        $this->taxCalculationService = $taxCalculationService;
         parent::__construct(
             $context,
             $data
@@ -236,15 +253,19 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
             return $this->_jsonEncoder->encode($config);
         }
 
-        $request = $this->_taxCalculation->getDefaultRateRequest();
+        $customerId = $this->getCustomerId();
         /* @var $product \Magento\Catalog\Model\Product */
         $product = $this->getProduct();
-        $request->setProductClassId($product->getTaxClassId());
-        $defaultTax = $this->_taxCalculation->getRate($request);
-
-        $request = $this->_taxCalculation->getRateRequest();
-        $request->setProductClassId($product->getTaxClassId());
-        $currentTax = $this->_taxCalculation->getRate($request);
+        $defaultTax = $this->taxCalculationService->getDefaultCalculatedRate(
+            $product->getTaxClassId(),
+            $customerId,
+            null
+        );
+        $currentTax = $this->taxCalculationService->getCalculatedRate(
+            $product->getTaxClassId(),
+            $customerId,
+            null
+        );
 
         $tierPrices = array();
 
@@ -394,4 +415,14 @@ class View extends AbstractProduct implements \Magento\Framework\View\Block\Iden
         }
         return $identities;
     }
+
+    /**
+     * Retrieve customer data object
+     *
+     * @return int
+     */
+    protected function getCustomerId()
+    {
+        return $this->customerSession->getCustomerId();
+    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
index e2b3ed2915361779d64871a4b1a6b66e0f535fae..1d4aa70d7f22d2bfc4ffa23ec63dab9bfb5401af 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category.php
@@ -78,496 +78,6 @@ class Category extends \Magento\Backend\App\Action
         return $category;
     }
 
-    /**
-     * Catalog categories index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Add new category form
-     *
-     * @return void
-     */
-    public function addAction()
-    {
-        $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->unsActiveTabId();
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit category page
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store');
-        $parentId = (int)$this->getRequest()->getParam('parent');
-        $categoryId = (int)$this->getRequest()->getParam('id');
-
-        if ($storeId && !$categoryId && !$parentId) {
-            $store = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore($storeId);
-            $this->getRequest()->setParam('id', (int)$store->getRootCategoryId());
-        }
-
-        $category = $this->_initCategory(true);
-        if (!$category) {
-            return;
-        }
-
-        $this->_title->add($categoryId ? $category->getName() : __('Categories'));
-
-        /**
-         * Check if we have data in session (if during category save was exception)
-         */
-        $data = $this->_getSession()->getCategoryData(true);
-        if (isset($data['general'])) {
-            $category->addData($data['general']);
-        }
-
-        /**
-         * Build response for ajax request
-         */
-        if ($this->getRequest()->getQuery('isAjax')) {
-            // prepare breadcrumbs of selected category, if any
-            $breadcrumbsPath = $category->getPath();
-            if (empty($breadcrumbsPath)) {
-                // but if no category, and it is deleted - prepare breadcrumbs from path, saved in session
-                $breadcrumbsPath = $this->_objectManager->get(
-                    'Magento\Backend\Model\Auth\Session'
-                )->getDeletedPath(
-                    true
-                );
-                if (!empty($breadcrumbsPath)) {
-                    $breadcrumbsPath = explode('/', $breadcrumbsPath);
-                    // no need to get parent breadcrumbs if deleting category level 1
-                    if (count($breadcrumbsPath) <= 1) {
-                        $breadcrumbsPath = '';
-                    } else {
-                        array_pop($breadcrumbsPath);
-                        $breadcrumbsPath = implode('/', $breadcrumbsPath);
-                    }
-                }
-            }
-
-            $this->_view->loadLayout();
-
-            $eventResponse = new \Magento\Framework\Object(
-                array(
-                    'content' => $this->_view->getLayout()->getBlock(
-                        'category.edit'
-                    )->getFormHtml() . $this->_view->getLayout()->getBlock(
-                        'category.tree'
-                    )->getBreadcrumbsJavascript(
-                        $breadcrumbsPath,
-                        'editingCategoryBreadcrumbs'
-                    ),
-                    'messages' => $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()
-                )
-            );
-            $this->_eventManager->dispatch(
-                'category_prepare_ajax_response',
-                array('response' => $eventResponse, 'controller' => $this)
-            );
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($eventResponse->getData())
-            );
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_categories');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true)->setContainerCssClass('catalog-categories');
-
-        $this->_addBreadcrumb(__('Manage Catalog Categories'), __('Manage Categories'));
-
-        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
-        if ($block) {
-            $block->setStoreId($storeId);
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * WYSIWYG editor action for ajax request
-     *
-     * @return void
-     */
-    public function wysiwygAction()
-    {
-        $elementId = $this->getRequest()->getParam('element_id', md5(microtime()));
-        $storeId = $this->getRequest()->getParam('store_id', 0);
-        $storeMediaUrl = $this->_objectManager->get(
-            'Magento\Store\Model\StoreManagerInterface'
-        )->getStore(
-            $storeId
-        )->getBaseUrl(
-            \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
-        );
-
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Catalog\Block\Adminhtml\Helper\Form\Wysiwyg\Content',
-            '',
-            array(
-                'data' => array(
-                    'editor_element_id' => $elementId,
-                    'store_id' => $storeId,
-                    'store_media_url' => $storeMediaUrl
-                )
-            )
-        );
-
-        $this->getResponse()->setBody($content->toHtml());
-    }
-
-    /**
-     * Get tree node (Ajax version)
-     *
-     * @return void
-     */
-    public function categoriesJsonAction()
-    {
-        if ($this->getRequest()->getParam('expand_all')) {
-            $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setIsTreeWasExpanded(true);
-        } else {
-            $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setIsTreeWasExpanded(false);
-        }
-        $categoryId = (int)$this->getRequest()->getPost('id');
-        if ($categoryId) {
-            $this->getRequest()->setParam('id', $categoryId);
-
-            if (!($category = $this->_initCategory())) {
-                return;
-            }
-            $this->getResponse()->representJson(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\Catalog\Block\Adminhtml\Category\Tree'
-                )->getTreeJson(
-                    $category
-                )
-            );
-        }
-    }
-
-    /**
-     * Category save
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        if (!($category = $this->_initCategory())) {
-            return;
-        }
-
-        $storeId = $this->getRequest()->getParam('store');
-        $refreshTree = 'false';
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $category->addData($this->_filterCategoryPostData($data['general']));
-            if (!$category->getId()) {
-                $parentId = $this->getRequest()->getParam('parent');
-                if (!$parentId) {
-                    if ($storeId) {
-                        $parentId = $this->_objectManager->get(
-                            'Magento\Store\Model\StoreManagerInterface'
-                        )->getStore(
-                            $storeId
-                        )->getRootCategoryId();
-                    } else {
-                        $parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
-                    }
-                }
-                $parentCategory = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($parentId);
-                $category->setPath($parentCategory->getPath());
-            }
-
-            /**
-             * Process "Use Config Settings" checkboxes
-             */
-            $useConfig = $this->getRequest()->getPost('use_config');
-            if ($useConfig) {
-                foreach ($useConfig as $attributeCode) {
-                    $category->setData($attributeCode, null);
-                }
-            }
-
-            /**
-             * Create Permanent Redirect for old URL key
-             */
-            // && $category->getOrigData('url_key') != $category->getData('url_key')
-            if ($category->getId() && isset($data['general']['url_key_create_redirect'])) {
-                $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
-            }
-
-            $category->setAttributeSetId($category->getDefaultAttributeSetId());
-
-            if (isset($data['category_products']) && !$category->getProductsReadonly()) {
-                $products = json_decode($data['category_products'], true);
-                $category->setPostedProducts($products);
-            }
-            $this->_eventManager->dispatch(
-                'catalog_category_prepare_save',
-                array('category' => $category, 'request' => $this->getRequest())
-            );
-
-            /**
-             * Check "Use Default Value" checkboxes values
-             */
-            $useDefaults = $this->getRequest()->getPost('use_default');
-            if ($useDefaults) {
-                foreach ($useDefaults as $attributeCode) {
-                    $category->setData($attributeCode, false);
-                }
-            }
-
-            /**
-             * Proceed with $_POST['use_config']
-             * set into category model for processing through validation
-             */
-            $category->setData('use_post_data_config', $this->getRequest()->getPost('use_config'));
-
-            try {
-                $validate = $category->validate();
-                if ($validate !== true) {
-                    foreach ($validate as $code => $error) {
-                        if ($error === true) {
-                            $attribute = $category->getResource()->getAttribute($code)->getFrontend()->getLabel();
-                            throw new \Magento\Framework\Model\Exception(__('Attribute "%1" is required.', $attribute));
-                        } else {
-                            throw new \Magento\Framework\Model\Exception($error);
-                        }
-                    }
-                }
-
-                $category->unsetData('use_post_data_config');
-                if (isset($data['general']['entity_id'])) {
-                    throw new \Magento\Framework\Model\Exception(__('Unable to save the category'));
-                }
-
-                $category->save();
-                $this->messageManager->addSuccess(__('You saved the category.'));
-                $refreshTree = 'true';
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_getSession()->setCategoryData($data);
-                $refreshTree = 'false';
-            }
-        }
-
-        if ($this->getRequest()->getPost('return_session_messages_only')) {
-            $category->load($category->getId());
-            // to obtain truncated category name
-
-            /** @var $block \Magento\Framework\View\Element\Messages */
-            $block = $this->_objectManager->get('Magento\Framework\View\Element\Messages');
-            $block->setMessages($this->messageManager->getMessages(true));
-            $body = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'messages' => $block->getGroupedHtml(),
-                    'error' => $refreshTree !== 'true',
-                    'category' => $category->toArray()
-                )
-            );
-        } else {
-            $url = $this->getUrl('catalog/*/edit', array('_current' => true, 'id' => $category->getId()));
-            $body = '<script type="text/javascript">parent.updateContent("' .
-                $url .
-                '", {}, ' .
-                $refreshTree .
-                ');</script>';
-        }
-
-        $this->getResponse()->setBody($body);
-    }
-
-    /**
-     * Filter category data
-     *
-     * @param array $rawData
-     * @return array
-     */
-    protected function _filterCategoryPostData(array $rawData)
-    {
-        $data = $rawData;
-        // @todo It is a workaround to prevent saving this data in category model and it has to be refactored in future
-        if (isset($data['image']) && is_array($data['image'])) {
-            $data['image_additional_data'] = $data['image'];
-            unset($data['image']);
-        }
-        return $data;
-    }
-
-    /**
-     * Move category action
-     *
-     * @return void
-     */
-    public function moveAction()
-    {
-        $category = $this->_initCategory();
-        if (!$category) {
-            $this->getResponse()->setBody(__('There was a category move error.'));
-            return;
-        }
-        /**
-         * New parent category identifier
-         */
-        $parentNodeId = $this->getRequest()->getPost('pid', false);
-        /**
-         * Category id after which we have put our category
-         */
-        $prevNodeId = $this->getRequest()->getPost('aid', false);
-
-        try {
-            $category->move($parentNodeId, $prevNodeId);
-            $this->getResponse()->setBody('SUCCESS');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->getResponse()->setBody($e->getMessage());
-        } catch (\Exception $e) {
-            $this->getResponse()->setBody(__('There was a category move error %1', $e));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Delete category action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $categoryId = (int)$this->getRequest()->getParam('id');
-        if ($categoryId) {
-            try {
-                $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
-                $this->_eventManager->dispatch('catalog_controller_category_delete', array('category' => $category));
-
-                $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setDeletedPath($category->getPath());
-
-                $category->delete();
-                $this->messageManager->addSuccess(__('You deleted the category.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->getResponse()->setRedirect($this->getUrl('catalog/*/edit', array('_current' => true)));
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Something went wrong while trying to delete the category.'));
-                $this->getResponse()->setRedirect($this->getUrl('catalog/*/edit', array('_current' => true)));
-                return;
-            }
-        }
-        $this->getResponse()->setRedirect($this->getUrl('catalog/*/', array('_current' => true, 'id' => null)));
-    }
-
-    /**
-     * Grid Action
-     * Display list of products related to current category
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $category = $this->_initCategory(true);
-        if (!$category) {
-            return;
-        }
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Catalog\Block\Adminhtml\Category\Tab\Product',
-                'category.product.grid'
-            )->toHtml()
-        );
-    }
-
-    /**
-     * Tree Action
-     * Retrieve category tree
-     *
-     * @return void
-     */
-    public function treeAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store');
-        $categoryId = (int)$this->getRequest()->getParam('id');
-
-        if ($storeId) {
-            if (!$categoryId) {
-                $store = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore($storeId);
-                $rootId = $store->getRootCategoryId();
-                $this->getRequest()->setParam('id', $rootId);
-            }
-        }
-
-        $category = $this->_initCategory(true);
-
-        $block = $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Category\Tree');
-        $root = $block->getRoot();
-        $this->getResponse()->representJson(
-            $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'data' => $block->getTree(),
-                    'parameters' => array(
-                        'text' => $block->buildNodeName($root),
-                        'draggable' => false,
-                        'allowDrop' => (bool)$root->getIsVisible(),
-                        'id' => (int)$root->getId(),
-                        'expanded' => (int)$block->getIsWasExpanded(),
-                        'store_id' => (int)$block->getStore()->getId(),
-                        'category_id' => (int)$category->getId(),
-                        'root_visible' => (int)$root->getIsVisible()
-                    )
-                )
-            )
-        );
-    }
-
-    /**
-     * Build response for refresh input element 'path' in form
-     *
-     * @return void
-     */
-    public function refreshPathAction()
-    {
-        $categoryId = (int)$this->getRequest()->getParam('id');
-        if ($categoryId) {
-            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
-            $this->getResponse()->representJson(
-                $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->jsonEncode(
-                    array('id' => $categoryId, 'path' => $category->getPath())
-                )
-            );
-        }
-    }
-
-    /**
-     * Category list suggestion based on already entered symbols
-     *
-     * @return void
-     */
-    public function suggestCategoriesAction()
-    {
-        $this->getResponse()->representJson(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Catalog\Block\Adminhtml\Category\Tree'
-            )->getSuggestedCategoriesJson(
-                $this->getRequest()->getParam('label_part')
-            )
-        );
-    }
-
     /**
      * Check if admin has permissions to visit related pages
      *
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Add.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..59dcbb4211e978b5cecc5846d86baeca202692d6
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Add.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Add extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Add new category form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->unsActiveTabId();
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/CategoriesJson.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/CategoriesJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0b55d088e567c2d2dc9481e3a5c9b55cad3c9c2
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/CategoriesJson.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class CategoriesJson extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Get tree node (Ajax version)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('expand_all')) {
+            $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setIsTreeWasExpanded(true);
+        } else {
+            $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setIsTreeWasExpanded(false);
+        }
+        $categoryId = (int)$this->getRequest()->getPost('id');
+        if ($categoryId) {
+            $this->getRequest()->setParam('id', $categoryId);
+
+            if (!($category = $this->_initCategory())) {
+                return;
+            }
+            $this->getResponse()->representJson(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\Catalog\Block\Adminhtml\Category\Tree'
+                )->getTreeJson(
+                    $category
+                )
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..46afd2d586f2532eaf685d93b49146d1e2539bda
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Delete.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Delete extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Delete category action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $categoryId = (int)$this->getRequest()->getParam('id');
+        if ($categoryId) {
+            try {
+                $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
+                $this->_eventManager->dispatch('catalog_controller_category_delete', array('category' => $category));
+
+                $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->setDeletedPath($category->getPath());
+
+                $category->delete();
+                $this->messageManager->addSuccess(__('You deleted the category.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->getResponse()->setRedirect($this->getUrl('catalog/*/edit', array('_current' => true)));
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong while trying to delete the category.'));
+                $this->getResponse()->setRedirect($this->getUrl('catalog/*/edit', array('_current' => true)));
+                return;
+            }
+        }
+        $this->getResponse()->setRedirect($this->getUrl('catalog/*/', array('_current' => true, 'id' => null)));
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c6693caa1ba060eb60ab9e6b947b7a136307cb1
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Edit.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Edit category page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store');
+        $parentId = (int)$this->getRequest()->getParam('parent');
+        $categoryId = (int)$this->getRequest()->getParam('id');
+
+        if ($storeId && !$categoryId && !$parentId) {
+            $store = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore($storeId);
+            $this->getRequest()->setParam('id', (int)$store->getRootCategoryId());
+        }
+
+        $category = $this->_initCategory(true);
+        if (!$category) {
+            return;
+        }
+
+        $this->_title->add($categoryId ? $category->getName() : __('Categories'));
+
+        /**
+         * Check if we have data in session (if during category save was exception)
+         */
+        $data = $this->_getSession()->getCategoryData(true);
+        if (isset($data['general'])) {
+            $category->addData($data['general']);
+        }
+
+        /**
+         * Build response for ajax request
+         */
+        if ($this->getRequest()->getQuery('isAjax')) {
+            // prepare breadcrumbs of selected category, if any
+            $breadcrumbsPath = $category->getPath();
+            if (empty($breadcrumbsPath)) {
+                // but if no category, and it is deleted - prepare breadcrumbs from path, saved in session
+                $breadcrumbsPath = $this->_objectManager->get(
+                    'Magento\Backend\Model\Auth\Session'
+                )->getDeletedPath(
+                    true
+                );
+                if (!empty($breadcrumbsPath)) {
+                    $breadcrumbsPath = explode('/', $breadcrumbsPath);
+                    // no need to get parent breadcrumbs if deleting category level 1
+                    if (count($breadcrumbsPath) <= 1) {
+                        $breadcrumbsPath = '';
+                    } else {
+                        array_pop($breadcrumbsPath);
+                        $breadcrumbsPath = implode('/', $breadcrumbsPath);
+                    }
+                }
+            }
+
+            $this->_view->loadLayout();
+
+            $eventResponse = new \Magento\Framework\Object(
+                array(
+                    'content' => $this->_view->getLayout()->getBlock(
+                        'category.edit'
+                    )->getFormHtml() . $this->_view->getLayout()->getBlock(
+                        'category.tree'
+                    )->getBreadcrumbsJavascript(
+                        $breadcrumbsPath,
+                        'editingCategoryBreadcrumbs'
+                    ),
+                    'messages' => $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml()
+                )
+            );
+            $this->_eventManager->dispatch(
+                'category_prepare_ajax_response',
+                array('response' => $eventResponse, 'controller' => $this)
+            );
+            $this->getResponse()->setHeader('Content-type', 'application/json', true);
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($eventResponse->getData())
+            );
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_categories');
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true)->setContainerCssClass('catalog-categories');
+
+        $this->_addBreadcrumb(__('Manage Catalog Categories'), __('Manage Categories'));
+
+        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
+        if ($block) {
+            $block->setStoreId($storeId);
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Grid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..d816d429a7901c5a68e2c031b3e85352c68cbc7c
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Grid.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Grid extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Grid Action
+     * Display list of products related to current category
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $category = $this->_initCategory(true);
+        if (!$category) {
+            return;
+        }
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Catalog\Block\Adminhtml\Category\Tab\Product',
+                'category.product.grid'
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f6d8a0a128e735c88d7b7061d8920bed029561f
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Catalog categories index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
new file mode 100644
index 0000000000000000000000000000000000000000..35e97e141795ce07d107328ec1f43dd032b4aff9
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Move.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Move extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Move category action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $category = $this->_initCategory();
+        if (!$category) {
+            $this->getResponse()->setBody(__('There was a category move error.'));
+            return;
+        }
+        /**
+         * New parent category identifier
+         */
+        $parentNodeId = $this->getRequest()->getPost('pid', false);
+        /**
+         * Category id after which we have put our category
+         */
+        $prevNodeId = $this->getRequest()->getPost('aid', false);
+
+        try {
+            $category->move($parentNodeId, $prevNodeId);
+            $this->getResponse()->setBody('SUCCESS');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->getResponse()->setBody($e->getMessage());
+        } catch (\Exception $e) {
+            $this->getResponse()->setBody(__('There was a category move error %1', $e));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/RefreshPath.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/RefreshPath.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f069b2c56e0407d53a2fdc40440e7371f7caa42
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/RefreshPath.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class RefreshPath extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Build response for refresh input element 'path' in form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $categoryId = (int)$this->getRequest()->getParam('id');
+        if ($categoryId) {
+            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
+            $this->getResponse()->representJson(
+                $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->jsonEncode(
+                    array('id' => $categoryId, 'path' => $category->getPath())
+                )
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..03178387ebc1559c3d5965844e75f32f296e835c
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Save.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Filter category data
+     *
+     * @param array $rawData
+     * @return array
+     */
+    protected function _filterCategoryPostData(array $rawData)
+    {
+        $data = $rawData;
+        // @todo It is a workaround to prevent saving this data in category model and it has to be refactored in future
+        if (isset($data['image']) && is_array($data['image'])) {
+            $data['image_additional_data'] = $data['image'];
+            unset($data['image']);
+        }
+        return $data;
+    }
+
+    /**
+     * Category save
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!($category = $this->_initCategory())) {
+            return;
+        }
+
+        $storeId = $this->getRequest()->getParam('store');
+        $refreshTree = 'false';
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $category->addData($this->_filterCategoryPostData($data['general']));
+            if (!$category->getId()) {
+                $parentId = $this->getRequest()->getParam('parent');
+                if (!$parentId) {
+                    if ($storeId) {
+                        $parentId = $this->_objectManager->get(
+                            'Magento\Store\Model\StoreManagerInterface'
+                        )->getStore(
+                            $storeId
+                        )->getRootCategoryId();
+                    } else {
+                        $parentId = \Magento\Catalog\Model\Category::TREE_ROOT_ID;
+                    }
+                }
+                $parentCategory = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($parentId);
+                $category->setPath($parentCategory->getPath());
+            }
+
+            /**
+             * Process "Use Config Settings" checkboxes
+             */
+            $useConfig = $this->getRequest()->getPost('use_config');
+            if ($useConfig) {
+                foreach ($useConfig as $attributeCode) {
+                    $category->setData($attributeCode, null);
+                }
+            }
+
+            /**
+             * Create Permanent Redirect for old URL key
+             */
+            // && $category->getOrigData('url_key') != $category->getData('url_key')
+            if ($category->getId() && isset($data['general']['url_key_create_redirect'])) {
+                $category->setData('save_rewrites_history', (bool)$data['general']['url_key_create_redirect']);
+            }
+
+            $category->setAttributeSetId($category->getDefaultAttributeSetId());
+
+            if (isset($data['category_products']) && !$category->getProductsReadonly()) {
+                $products = json_decode($data['category_products'], true);
+                $category->setPostedProducts($products);
+            }
+            $this->_eventManager->dispatch(
+                'catalog_category_prepare_save',
+                array('category' => $category, 'request' => $this->getRequest())
+            );
+
+            /**
+             * Check "Use Default Value" checkboxes values
+             */
+            $useDefaults = $this->getRequest()->getPost('use_default');
+            if ($useDefaults) {
+                foreach ($useDefaults as $attributeCode) {
+                    $category->setData($attributeCode, false);
+                }
+            }
+
+            /**
+             * Proceed with $_POST['use_config']
+             * set into category model for processing through validation
+             */
+            $category->setData('use_post_data_config', $this->getRequest()->getPost('use_config'));
+
+            try {
+                $validate = $category->validate();
+                if ($validate !== true) {
+                    foreach ($validate as $code => $error) {
+                        if ($error === true) {
+                            $attribute = $category->getResource()->getAttribute($code)->getFrontend()->getLabel();
+                            throw new \Magento\Framework\Model\Exception(__('Attribute "%1" is required.', $attribute));
+                        } else {
+                            throw new \Magento\Framework\Model\Exception($error);
+                        }
+                    }
+                }
+
+                $category->unsetData('use_post_data_config');
+                if (isset($data['general']['entity_id'])) {
+                    throw new \Magento\Framework\Model\Exception(__('Unable to save the category'));
+                }
+
+                $category->save();
+                $this->messageManager->addSuccess(__('You saved the category.'));
+                $refreshTree = 'true';
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_getSession()->setCategoryData($data);
+                $refreshTree = 'false';
+            }
+        }
+
+        if ($this->getRequest()->getPost('return_session_messages_only')) {
+            $category->load($category->getId());
+            // to obtain truncated category name
+
+            /** @var $block \Magento\Framework\View\Element\Messages */
+            $block = $this->_objectManager->get('Magento\Framework\View\Element\Messages');
+            $block->setMessages($this->messageManager->getMessages(true));
+            $body = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'messages' => $block->getGroupedHtml(),
+                    'error' => $refreshTree !== 'true',
+                    'category' => $category->toArray()
+                )
+            );
+        } else {
+            $url = $this->getUrl('catalog/*/edit', array('_current' => true, 'id' => $category->getId()));
+            $body = '<script type="text/javascript">parent.updateContent("' .
+                $url .
+                '", {}, ' .
+                $refreshTree .
+                ');</script>';
+        }
+
+        $this->getResponse()->setBody($body);
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/SuggestCategories.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/SuggestCategories.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcea9b292c77a89e3c744e75450988882078d5d8
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/SuggestCategories.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class SuggestCategories extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Category list suggestion based on already entered symbols
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->representJson(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Catalog\Block\Adminhtml\Category\Tree'
+            )->getSuggestedCategoriesJson(
+                $this->getRequest()->getParam('label_part')
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Tree.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Tree.php
new file mode 100644
index 0000000000000000000000000000000000000000..857c6e69af5992dea2b050553a62dee8da6206ac
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Tree.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Tree extends \Magento\Catalog\Controller\Adminhtml\Category
+{
+    /**
+     * Tree Action
+     * Retrieve category tree
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store');
+        $categoryId = (int)$this->getRequest()->getParam('id');
+
+        if ($storeId) {
+            if (!$categoryId) {
+                $store = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore($storeId);
+                $rootId = $store->getRootCategoryId();
+                $this->getRequest()->setParam('id', $rootId);
+            }
+        }
+
+        $category = $this->_initCategory(true);
+
+        $block = $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Category\Tree');
+        $root = $block->getRoot();
+        $this->getResponse()->representJson(
+            $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'data' => $block->getTree(),
+                    'parameters' => array(
+                        'text' => $block->buildNodeName($root),
+                        'draggable' => false,
+                        'allowDrop' => (bool)$root->getIsVisible(),
+                        'id' => (int)$root->getId(),
+                        'expanded' => (int)$block->getIsWasExpanded(),
+                        'store_id' => (int)$block->getStore()->getId(),
+                        'category_id' => (int)$category->getId(),
+                        'root_visible' => (int)$root->getIsVisible()
+                    )
+                )
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php
index 72b8c542ec160f769491a52587bf50df12b40af8..fcc0436c3725d8a5364fb117fe45c9e4677214e9 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget.php
@@ -32,53 +32,6 @@ use Magento\Framework\View\Element\BlockInterface;
  */
 class Widget extends \Magento\Backend\App\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
-    /**
-     * Chooser Source action
-     *
-     * @return void
-     */
-    public function chooserAction()
-    {
-        $this->getResponse()->setBody($this->_getCategoryTreeBlock()->toHtml());
-    }
-
-    /**
-     * Categories tree node (Ajax version)
-     *
-     * @return void
-     */
-    public function categoriesJsonAction()
-    {
-        $categoryId = (int)$this->getRequest()->getPost('id');
-        if ($categoryId) {
-            $selected = $this->getRequest()->getPost('selected', '');
-            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
-            if ($category->getId()) {
-                $this->_coreRegistry->register('category', $category);
-                $this->_coreRegistry->register('current_category', $category);
-            }
-            $categoryTreeBlock = $this->_getCategoryTreeBlock()->setSelectedCategories(explode(',', $selected));
-            $this->getResponse()->representJson($categoryTreeBlock->getTreeJson($category));
-        }
-    }
-
     /**
      * @return BlockInterface
      */
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJson.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..30cb4fcd30c9b85153070b5d986c0fbda12777ec
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJson.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category\Widget;
+
+class CategoriesJson extends \Magento\Catalog\Controller\Adminhtml\Category\Widget
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Categories tree node (Ajax version)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $categoryId = (int)$this->getRequest()->getPost('id');
+        if ($categoryId) {
+            $selected = $this->getRequest()->getPost('selected', '');
+            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
+            if ($category->getId()) {
+                $this->_coreRegistry->register('category', $category);
+                $this->_coreRegistry->register('current_category', $category);
+            }
+            $categoryTreeBlock = $this->_getCategoryTreeBlock()->setSelectedCategories(explode(',', $selected));
+            $this->getResponse()->representJson($categoryTreeBlock->getTreeJson($category));
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/Chooser.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/Chooser.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2b6c49eebf1f06fd178d554e26a5d3a9efd6830
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Widget/Chooser.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category\Widget;
+
+class Chooser extends \Magento\Catalog\Controller\Adminhtml\Category\Widget
+{
+    /**
+     * Chooser Source action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody($this->_getCategoryTreeBlock()->toHtml());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Category/Wysiwyg.php b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Wysiwyg.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c38799012594dd383ed73fd5af0f7b9f37653bf
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Category/Wysiwyg.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category;
+
+class Wysiwyg extends \Magento\Catalog\Controller\Adminhtml\Product\Wysiwyg
+{
+    /**
+     * Check if admin has permissions to visit related pages
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Catalog::categories');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
index 400d9c773e21710432a3f19e279578963a990aad..9c92721e5b61590d06861411584d91be649c89f4 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product.php
@@ -24,706 +24,29 @@
 namespace Magento\Catalog\Controller\Adminhtml;
 
 use Magento\Backend\App\Action;
-use Magento\Catalog\Model\Product\Validator;
 
 /**
  * Catalog product controller
  */
 class Product extends \Magento\Backend\App\Action
 {
-    /**
-     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
-     */
-    protected $_productPriceIndexerProcessor;
-
-    /**
-     * Array of actions which can be processed without secret key validation
-     *
-     * @var array
-     */
-    protected $_publicActions = array('edit');
-
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $registry;
-
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime\Filter\Date
-     */
-    protected $_dateFilter;
-
-    /**
-     * @var Product\Initialization\Helper
-     */
-    protected $initializationHelper;
-
-    /**
-     * @var Product\Initialization\StockDataFilter
-     */
-    protected $stockFilter;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Copier
-     */
-    protected $productCopier;
-
     /**
      * @var Product\Builder
      */
     protected $productBuilder;
 
-    /**
-     * @var \Magento\Catalog\Model\Product\TypeTransitionManager
-     */
-    protected $productTypeManager;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Validator
-     */
-    protected $productValidator;
-
     /**
      * @param Action\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
-     * @param Product\Initialization\Helper $initializationHelper
-     * @param Product\Initialization\StockDataFilter $stockFilter
-     * @param \Magento\Catalog\Model\Product\Copier $productCopier
      * @param Product\Builder $productBuilder
-     * @param Validator $productValidator
-     * @param \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager
-     * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
      */
     public function __construct(
         \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
-        \Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper $initializationHelper,
-        \Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter $stockFilter,
-        \Magento\Catalog\Model\Product\Copier $productCopier,
-        Product\Builder $productBuilder,
-        Validator $productValidator,
-        \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager,
-        \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
+        Product\Builder $productBuilder
     ) {
-        $this->stockFilter = $stockFilter;
-        $this->initializationHelper = $initializationHelper;
-        $this->registry = $registry;
-        $this->_dateFilter = $dateFilter;
-        $this->productCopier = $productCopier;
-        $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
         $this->productBuilder = $productBuilder;
-        $this->productValidator = $productValidator;
-        $this->productTypeManager = $productTypeManager;
         parent::__construct($context);
     }
 
-    /**
-     * Create serializer block for a grid
-     *
-     * @param string $inputName
-     * @param \Magento\Backend\Block\Widget\Grid $gridBlock
-     * @param array $productsArray
-     * @return \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Ajax\Serializer
-     */
-    protected function _createSerializerBlock(
-        $inputName,
-        \Magento\Backend\Block\Widget\Grid $gridBlock,
-        $productsArray
-    ) {
-        return $this->_view->getLayout()
-            ->createBlock('Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Ajax\Serializer')
-            ->setGridBlock($gridBlock)
-            ->setProducts($productsArray)
-            ->setInputElementName($inputName);
-    }
-
-    /**
-     * Output specified blocks as a text list
-     *
-     * @return void
-     */
-    protected function _outputBlocks()
-    {
-        $blocks = func_get_args();
-        $output = $this->_view->getLayout()->createBlock('Magento\Backend\Block\Text\ListText');
-        foreach ($blocks as $block) {
-            $output->insert($block, '', true);
-        }
-        $this->getResponse()->setBody($output->toHtml());
-    }
-
-    /**
-     * Product list page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Products'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_products');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new product page
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        if (!$this->getRequest()->getParam('set')) {
-            $this->_forward('noroute');
-            return;
-        }
-        $this->_title->add(__('Products'));
-
-        $product = $this->productBuilder->build($this->getRequest());
-
-        $productData = $this->getRequest()->getPost('product');
-        if ($productData) {
-            $stockData = isset($productData['stock_data']) ? $productData['stock_data'] : array();
-            $productData['stock_data'] = $this->stockFilter->filter($stockData);
-            $product->addData($productData);
-        }
-
-        $this->_title->add(__('New Product'));
-
-        $this->_eventManager->dispatch('catalog_product_new_action', array('product' => $product));
-
-        if ($this->getRequest()->getParam('popup')) {
-            $this->_view->loadLayout(array(
-                'popup',
-                strtolower($this->_request->getFullActionName()),
-                'catalog_product_' . $product->getTypeId()
-            ));
-        } else {
-            $this->_view->loadLayout(
-                array(
-                    'default',
-                    strtolower($this->_request->getFullActionName()),
-                    'catalog_product_' . $product->getTypeId()
-                )
-            );
-            $this->_setActiveMenu('Magento_Catalog::catalog_products');
-        }
-
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
-        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
-        if ($block) {
-            $block->setStoreId($product->getStoreId());
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Product edit form
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Products'));
-        $productId = (int) $this->getRequest()->getParam('id');
-        $product = $this->productBuilder->build($this->getRequest());
-
-        if ($productId && !$product->getId()) {
-            $this->messageManager->addError(__('This product no longer exists.'));
-            $this->_redirect('catalog/*/');
-            return;
-        }
-
-        $this->_title->add($product->getName());
-
-        $this->_eventManager->dispatch('catalog_product_edit_action', array('product' => $product));
-
-        $this->_view->loadLayout(
-            array(
-                'default',
-                strtolower($this->_request->getFullActionName()),
-                'catalog_product_' . $product->getTypeId()
-            )
-        );
-
-        $this->_setActiveMenu('Magento_Catalog::catalog_products');
-
-        if (!$this->_objectManager->get(
-            'Magento\Store\Model\StoreManagerInterface'
-        )->isSingleStoreMode() && ($switchBlock = $this->_view->getLayout()->getBlock(
-            'store_switcher'
-        ))
-        ) {
-            $switchBlock->setDefaultStoreName(__('Default Values'))
-                ->setWebsiteIds($product->getWebsiteIds())
-                ->setSwitchUrl(
-                    $this->getUrl(
-                        'catalog/*/*',
-                        array('_current' => true, 'active_tab' => null, 'tab' => null, 'store' => null)
-                    )
-                );
-        }
-
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
-        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
-        if ($block) {
-            $block->setStoreId($product->getStoreId());
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * WYSIWYG editor action for ajax request
-     *
-     * @return void
-     */
-    public function wysiwygAction()
-    {
-        $elementId = $this->getRequest()->getParam('element_id', md5(microtime()));
-        $storeId = $this->getRequest()->getParam('store_id', 0);
-        $storeMediaUrl = $this->_objectManager->get(
-            'Magento\Store\Model\StoreManagerInterface'
-        )->getStore(
-            $storeId
-        )->getBaseUrl(
-            \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
-        );
-
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Catalog\Block\Adminhtml\Helper\Form\Wysiwyg\Content',
-            '',
-            array(
-                'data' => array(
-                    'editor_element_id' => $elementId,
-                    'store_id' => $storeId,
-                    'store_media_url' => $storeMediaUrl
-                )
-            )
-        );
-        $this->getResponse()->setBody($content->toHtml());
-    }
-
-    /**
-     * Product grid for AJAX request
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get specified tab grid
-     *
-     * @return void
-     */
-    public function gridOnlyAction()
-    {
-        $this->_title->add(__('Products'));
-
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-
-        $block = $this->getRequest()->getParam('gridOnlyBlock');
-        $blockClassSuffix = str_replace(' ', '_', ucwords(str_replace('_', ' ', $block)));
-
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\\' . $blockClassSuffix
-            )->toHtml()
-        );
-    }
-
-    /**
-     * Get categories fieldset block
-     *
-     * @return void
-     */
-    public function categoriesAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get options fieldset block
-     *
-     * @return void
-     */
-    public function optionsAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get related products grid and serializer block
-     *
-     * @return void
-     */
-    public function relatedAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.related')
-            ->setProductsRelated($this->getRequest()->getPost('products_related', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get upsell products grid and serializer block
-     *
-     * @return void
-     */
-    public function upsellAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.upsell')
-            ->setProductsUpsell($this->getRequest()->getPost('products_upsell', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get crosssell products grid and serializer block
-     *
-     * @return void
-     */
-    public function crosssellAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.crosssell')
-            ->setProductsCrossSell($this->getRequest()->getPost('products_crosssell', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get related products grid
-     *
-     * @return void
-     */
-    public function relatedGridAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.related')
-            ->setProductsRelated($this->getRequest()->getPost('products_related', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get upsell products grid
-     *
-     * @return void
-     */
-    public function upsellGridAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.upsell')
-            ->setProductsRelated($this->getRequest()->getPost('products_upsell', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get crosssell products grid
-     *
-     * @return void
-     */
-    public function crosssellGridAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.crosssell')
-            ->setProductsRelated($this->getRequest()->getPost('products_crosssell', null));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Validate product
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(false);
-
-        try {
-            $productData = $this->getRequest()->getPost('product');
-
-            if ($productData && !isset($productData['stock_data']['use_config_manage_stock'])) {
-                $productData['stock_data']['use_config_manage_stock'] = 0;
-            }
-            /* @var $product \Magento\Catalog\Model\Product */
-            $product = $this->_objectManager->create('Magento\Catalog\Model\Product');
-            $product->setData('_edit_mode', true);
-            $storeId = $this->getRequest()->getParam('store');
-            if ($storeId) {
-                $product->setStoreId($storeId);
-            }
-            $setId = $this->getRequest()->getParam('set');
-            if ($setId) {
-                $product->setAttributeSetId($setId);
-            }
-            $typeId = $this->getRequest()->getParam('type');
-            if ($typeId) {
-                $product->setTypeId($typeId);
-            }
-            $productId = $this->getRequest()->getParam('id');
-            if ($productId) {
-                $product->load($productId);
-            }
-
-            $dateFieldFilters = array();
-            $attributes = $product->getAttributes();
-            foreach ($attributes as $attrKey => $attribute) {
-                if ($attribute->getBackend()->getType() == 'datetime') {
-                    if (array_key_exists($attrKey, $productData) && $productData[$attrKey] != '') {
-                        $dateFieldFilters[$attrKey] = $this->_dateFilter;
-                    }
-                }
-            }
-            $inputFilter = new \Zend_Filter_Input($dateFieldFilters, array(), $productData);
-            $productData = $inputFilter->getUnescaped();
-            $product->addData($productData);
-
-            /* set restrictions for date ranges */
-            $resource = $product->getResource();
-            $resource->getAttribute('special_from_date')->setMaxValue($product->getSpecialToDate());
-            $resource->getAttribute('news_from_date')->setMaxValue($product->getNewsToDate());
-            $resource->getAttribute('custom_design_from')->setMaxValue($product->getCustomDesignTo());
-
-            $this->productValidator->validate($product, $this->getRequest(), $response);
-        } catch (\Magento\Eav\Model\Entity\Attribute\Exception $e) {
-            $response->setError(true);
-            $response->setAttribute($e->getAttributeCode());
-            $response->setMessage($e->getMessage());
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response->setError(true);
-            $response->setMessage($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_view->getLayout()->initMessages();
-            $response->setError(true);
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Save product action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $storeId = $this->getRequest()->getParam('store');
-        $redirectBack = $this->getRequest()->getParam('back', false);
-        $productId = $this->getRequest()->getParam('id');
-
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
-            $this->productTypeManager->processProduct($product);
-
-            try {
-                if (isset($data['product'][$product->getIdFieldName()])) {
-                    throw new \Magento\Framework\Model\Exception(__('Unable to save product'));
-                }
-
-                $originalSku = $product->getSku();
-                $product->save();
-                $productId = $product->getId();
-
-                /**
-                 * Do copying data to stores
-                 */
-                if (isset($data['copy_to_stores'])) {
-                    foreach ($data['copy_to_stores'] as $storeTo => $storeFrom) {
-                        $this->_objectManager->create('Magento\Catalog\Model\Product')
-                            ->setStoreId($storeFrom)
-                            ->load($productId)
-                            ->setStoreId($storeTo)
-                            ->save();
-                    }
-                }
-
-                $this->_objectManager->create('Magento\CatalogRule\Model\Rule')->applyAllRulesToProduct($productId);
-
-                $this->messageManager->addSuccess(__('You saved the product.'));
-                if ($product->getSku() != $originalSku) {
-                    $this->messageManager->addNotice(
-                        __(
-                            'SKU for product %1 has been changed to %2.',
-                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName()),
-                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getSku())
-                        )
-                    );
-                }
-
-                $this->_eventManager->dispatch(
-                    'controller_action_catalog_product_save_entity_after',
-                    array('controller' => $this)
-                );
-
-                if ($redirectBack === 'duplicate') {
-                    $newProduct = $this->productCopier->copy($product);
-                    $this->messageManager->addSuccess(__('You duplicated the product.'));
-                }
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_session->setProductData($data);
-                $redirectBack = true;
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError($e->getMessage());
-                $redirectBack = true;
-            }
-        }
-
-        if ($redirectBack === 'new') {
-            $this->_redirect(
-                'catalog/*/new',
-                array('set' => $product->getAttributeSetId(), 'type' => $product->getTypeId())
-            );
-        } elseif ($redirectBack === 'duplicate' && isset($newProduct)) {
-            $this->_redirect(
-                'catalog/*/edit',
-                array('id' => $newProduct->getId(), 'back' => null, '_current' => true)
-            );
-        } elseif ($redirectBack) {
-            $this->_redirect('catalog/*/edit', array('id' => $productId, '_current' => true));
-        } else {
-            $this->_redirect('catalog/*/', array('store' => $storeId));
-        }
-    }
-
-    /**
-     * Create product duplicate
-     *
-     * @return void
-     */
-    public function duplicateAction()
-    {
-        $product = $this->productBuilder->build($this->getRequest());
-        try {
-            $newProduct = $this->productCopier->copy($product);
-            $this->messageManager->addSuccess(__('You duplicated the product.'));
-            $this->_redirect('catalog/*/edit', array('_current' => true, 'id' => $newProduct->getId()));
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('catalog/*/edit', array('_current' => true));
-        }
-    }
-
-    /**
-     * Get alerts price grid
-     *
-     * @return void
-     */
-    public function alertsPriceGridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get alerts stock grid
-     *
-     * @return void
-     */
-    public function alertsStockGridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $productIds = $this->getRequest()->getParam('product');
-        if (!is_array($productIds) || empty($productIds)) {
-            $this->messageManager->addError(__('Please select product(s).'));
-        } else {
-            try {
-                foreach ($productIds as $productId) {
-                    $product = $this->_objectManager->get('Magento\Catalog\Model\Product')->load($productId);
-                    $product->delete();
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 record(s) have been deleted.', count($productIds))
-                );
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-        $this->_redirect('catalog/*/index');
-    }
-
-    /**
-     * Update product(s) status action
-     *
-     * @return void
-     */
-    public function massStatusAction()
-    {
-        $productIds = (array) $this->getRequest()->getParam('product');
-        $storeId = (int) $this->getRequest()->getParam('store', 0);
-        $status = (int) $this->getRequest()->getParam('status');
-
-        try {
-            $this->_validateMassStatus($productIds, $status);
-            $this->_objectManager->get('Magento\Catalog\Model\Product\Action')
-                ->updateAttributes($productIds, array('status' => $status), $storeId);
-            $this->messageManager->addSuccess(__('A total of %1 record(s) have been updated.', count($productIds)));
-            $this->_productPriceIndexerProcessor->reindexList($productIds);
-        } catch (\Magento\Core\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_getSession()->addException($e, __('Something went wrong while updating the product(s) status.'));
-        }
-
-        $this->_redirect('catalog/*/', array('store' => $storeId));
-    }
-
-    /**
-     * Validate batch of products before theirs status will be set
-     *
-     * @param array $productIds
-     * @param int $status
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function _validateMassStatus(array $productIds, $status)
-    {
-        if ($status == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
-            if (!$this->_objectManager->create('Magento\Catalog\Model\Product')->isProductsHasSku($productIds)) {
-                throw new \Magento\Framework\Model\Exception(
-                    __('Please make sure to define SKU values for all processed products.')
-                );
-            }
-        }
-    }
-
     /**
      * Check for is allowed
      *
@@ -733,125 +56,4 @@ class Product extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Catalog::products');
     }
-
-    /**
-     * Show item update result from updateAction
-     * in Wishlist and Cart controllers.
-     *
-     * @return bool
-     */
-    public function showUpdateResultAction()
-    {
-        $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-        if ($session->hasCompositeProductResult()
-            && $session->getCompositeProductResult() instanceof \Magento\Framework\Object
-        ) {
-            $this->_objectManager->get('Magento\Catalog\Helper\Product\Composite')
-                ->renderUpdateResult($session->getCompositeProductResult());
-            $session->unsCompositeProductResult();
-        } else {
-            $session->unsCompositeProductResult();
-            return false;
-        }
-    }
-
-    /**
-     * Show product grid for custom options import popup
-     *
-     * @return void
-     */
-    public function optionsImportGridAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Show custom options in JSON format for specified products
-     *
-     * @return void
-     */
-    public function customOptionsAction()
-    {
-        $this->registry->register('import_option_products', $this->getRequest()->getPost('products'));
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Action for product template selector
-     *
-     * @return void
-     */
-    public function suggestProductTemplatesAction()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
-                $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Product\TemplateSelector')
-                    ->getSuggestedTemplates($this->getRequest()->getParam('label_part'))
-            )
-        );
-    }
-
-    /**
-     * Search for attributes by part of attribute's label in admin store
-     *
-     * @return void
-     */
-    public function suggestAttributesAction()
-    {
-        $this->getResponse()->srepresentJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes\Search'
-                )->getSuggestedAttributes(
-                    $this->getRequest()->getParam('label_part')
-                )
-            )
-        );
-    }
-
-    /**
-     * Add attribute to product template
-     *
-     * @return void
-     */
-    public function addAttributeToTemplateAction()
-    {
-        $request = $this->getRequest();
-        try {
-            /** @var \Magento\Eav\Model\Entity\Attribute $attribute */
-            $attribute = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute')
-                ->load($request->getParam('attribute_id'));
-
-            $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
-                ->load($request->getParam('template_id'));
-
-            /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection $attributeGroupCollection */
-            $attributeGroupCollection = $this->_objectManager->get(
-                'Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection'
-            );
-            $attributeGroupCollection->setAttributeSetFilter($attributeSet->getId());
-            $attributeGroupCollection->addFilter('attribute_group_code', $request->getParam('group'));
-            $attributeGroupCollection->setPageSize(1);
-
-            $attributeGroup = $attributeGroupCollection->getFirstItem();
-
-            $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet();
-
-            $attribute->setEntityTypeId($attributeSet->getEntityTypeId())
-                ->setAttributeSetId($request->getParam('template_id'))
-                ->setAttributeGroupId($attributeGroup->getId())
-                ->setSortOrder('0')
-                ->save();
-
-            $this->getResponse()->representJson($attribute->toJson());
-        } catch (\Exception $e) {
-            $response = new \Magento\Framework\Object();
-            $response->setError(false);
-            $response->setMessage($e->getMessage());
-            $this->getResponse()->representJson($response->toJson());
-        }
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php
index 3b5b5442ccb415fa0f27e033c11e4cc905559bc6..9588f8c19b55ee1b44962f851ec75c9f104e2ee7 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute.php
@@ -31,192 +31,20 @@ use Magento\Backend\App\Action;
 class Attribute extends Action
 {
     /**
-     * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor
+     *  @var \Magento\Catalog\Helper\Product\Edit\Action\Attribute
      */
-    protected $_productFlatIndexerProcessor;
-
-    /**
-     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
-     */
-    protected $_productPriceIndexerProcessor;
-
-    /**
-     * Catalog product
-     *
-     * @var \Magento\Catalog\Helper\Product
-     */
-    protected $_catalogProduct;
-
-    /**
-     * @var \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder
-     */
-    protected $stockItemBuilder;
+    protected $attributeHelper;
 
     /**
      * @param Action\Context $context
-     * @param \Magento\Catalog\Helper\Product\Edit\Action\Attribute $helper
-     * @param \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor
-     * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
-     * @param \Magento\Catalog\Helper\Product $catalogProduct
-     * @param \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder
+     * @param \Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeHelper
      */
     public function __construct(
         Action\Context $context,
-        \Magento\Catalog\Helper\Product\Edit\Action\Attribute $helper,
-        \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
-        \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor,
-        \Magento\Catalog\Helper\Product $catalogProduct,
-        \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder
+        \Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeHelper
     ) {
         parent::__construct($context);
-        $this->_helper = $helper;
-        $this->_productFlatIndexerProcessor = $productFlatIndexerProcessor;
-        $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
-        $this->_catalogProduct = $catalogProduct;
-        $this->stockItemBuilder = $stockItemBuilder;
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        if (!$this->_validateProducts()) {
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Update product attributes
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        if (!$this->_validateProducts()) {
-            return;
-        }
-
-        /* Collect Data */
-        $inventoryData = $this->getRequest()->getParam('inventory', array());
-        $attributesData = $this->getRequest()->getParam('attributes', array());
-        $websiteRemoveData = $this->getRequest()->getParam('remove_website_ids', array());
-        $websiteAddData = $this->getRequest()->getParam('add_website_ids', array());
-
-        /* Prepare inventory data item options (use config settings) */
-        $options = $this->_objectManager->get('Magento\CatalogInventory\Helper\Data')->getConfigItemOptions();
-        foreach ($options as $option) {
-            if (isset($inventoryData[$option]) && !isset($inventoryData['use_config_' . $option])) {
-                $inventoryData['use_config_' . $option] = 0;
-            }
-        }
-
-        try {
-            if ($attributesData) {
-                $dateFormat = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface')
-                    ->getDateFormat(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT);
-                $storeId = $this->_helper->getSelectedStoreId();
-
-                foreach ($attributesData as $attributeCode => $value) {
-                    $attribute = $this->_objectManager->get('Magento\Eav\Model\Config')
-                        ->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode);
-                    if (!$attribute->getAttributeId()) {
-                        unset($attributesData[$attributeCode]);
-                        continue;
-                    }
-                    if ($attribute->getBackendType() == 'datetime') {
-                        if (!empty($value)) {
-                            $filterInput = new \Zend_Filter_LocalizedToNormalized(array('date_format' => $dateFormat));
-                            $filterInternal = new \Zend_Filter_NormalizedToLocalized(
-                                array('date_format' => \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT)
-                            );
-                            $value = $filterInternal->filter($filterInput->filter($value));
-                        } else {
-                            $value = null;
-                        }
-                        $attributesData[$attributeCode] = $value;
-                    } elseif ($attribute->getFrontendInput() == 'multiselect') {
-                        // Check if 'Change' checkbox has been checked by admin for this attribute
-                        $isChanged = (bool) $this->getRequest()->getPost($attributeCode . '_checkbox');
-                        if (!$isChanged) {
-                            unset($attributesData[$attributeCode]);
-                            continue;
-                        }
-                        if (is_array($value)) {
-                            $value = implode(',', $value);
-                        }
-                        $attributesData[$attributeCode] = $value;
-                    }
-                }
-
-                $this->_objectManager->get('Magento\Catalog\Model\Product\Action')
-                    ->updateAttributes($this->_helper->getProductIds(), $attributesData, $storeId);
-            }
-            if ($inventoryData) {
-                /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */
-                $stockItemService = $this->_objectManager
-                    ->create('Magento\CatalogInventory\Service\V1\StockItemService');
-
-                foreach ($this->_helper->getProductIds() as $productId) {
-                    $stockItemDo = $stockItemService->getStockItem($productId);
-                    if (!$stockItemDo->getProductId()) {
-                        $inventoryData[] = $productId;
-                    }
-
-                    $stockItemService->saveStockItem(
-                        $this->stockItemBuilder->mergeDataObjectWithArray($stockItemDo, $inventoryData)
-                    );
-                }
-            }
-
-            if ($websiteAddData || $websiteRemoveData) {
-                /* @var $actionModel \Magento\Catalog\Model\Product\Action */
-                $actionModel = $this->_objectManager->get('Magento\Catalog\Model\Product\Action');
-                $productIds = $this->_helper->getProductIds();
-
-                if ($websiteRemoveData) {
-                    $actionModel->updateWebsites($productIds, $websiteRemoveData, 'remove');
-                }
-                if ($websiteAddData) {
-                    $actionModel->updateWebsites($productIds, $websiteAddData, 'add');
-                }
-
-                $this->_eventManager->dispatch('catalog_product_to_website_change', array('products' => $productIds));
-
-                $this->messageManager->addNotice(
-                    __(
-                        'Please refresh "Catalog URL Rewrites" and "Product Attributes" in System -> ' .
-                        '<a href="%1">Index Management</a>.',
-                        $this->getUrl('adminhtml/process/list')
-                    )
-                );
-            }
-
-            $this->messageManager->addSuccess(
-                __('A total of %1 record(s) were updated.', count($this->_helper->getProductIds()))
-            );
-
-            $this->_productFlatIndexerProcessor->reindexList($this->_helper->getProductIds());
-
-            if ($this->_catalogProduct->isDataForPriceIndexerWasChanged($attributesData)
-                || !empty($websiteRemoveData)
-                || !empty($websiteAddData)
-            ) {
-                $this->_productPriceIndexerProcessor->reindexList($this->_helper->getProductIds());
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException(
-                $e,
-                __('Something went wrong while updating the product(s) attributes.')
-            );
-        }
-
-        $this->_redirect('catalog/product/', array('store' => $this->_helper->getSelectedStoreId()));
+        $this->attributeHelper = $attributeHelper;
     }
 
     /**
@@ -227,7 +55,7 @@ class Attribute extends Action
     protected function _validateProducts()
     {
         $error = false;
-        $productIds = $this->_helper->getProductIds();
+        $productIds = $this->attributeHelper->getProductIds();
         if (!is_array($productIds)) {
             $error = __('Please select products for attributes update.');
         } elseif (!$this->_objectManager->create('Magento\Catalog\Model\Product')->isProductsHasSku($productIds)) {
@@ -249,49 +77,4 @@ class Attribute extends Action
     {
         return $this->_authorization->isAllowed('Magento_Catalog::update_attributes');
     }
-
-    /**
-     * Attributes validation action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(false);
-        $attributesData = $this->getRequest()->getParam('attributes', array());
-        $data = new \Magento\Framework\Object();
-
-        try {
-            if ($attributesData) {
-                foreach ($attributesData as $attributeCode => $value) {
-                    $attribute = $this->_objectManager->get('Magento\Eav\Model\Config')
-                        ->getAttribute('catalog_product', $attributeCode);
-                    if (!$attribute->getAttributeId()) {
-                        unset($attributesData[$attributeCode]);
-                        continue;
-                    }
-                    $data->setData($attributeCode, $value);
-                    $attribute->getBackend()->validate($data);
-                }
-            }
-        } catch (\Magento\Eav\Model\Entity\Attribute\Exception $e) {
-            $response->setError(true);
-            $response->setAttribute($e->getAttributeCode());
-            $response->setMessage($e->getMessage());
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response->setError(true);
-            $response->setMessage($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException(
-                $e,
-                __('Something went wrong while updating the product(s) attributes.')
-            );
-            $this->_view->getLayout()->initMessages();
-            $response->setError(true);
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..f474824abbcf92f5d3d0e4f4febb441e85af88f2
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Edit.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateProducts()) {
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1d9f92e29413288ebd509f4f7f5ac9755e9499f
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Save.php
@@ -0,0 +1,217 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute;
+
+use Magento\Backend\App\Action;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor
+     */
+    protected $_productFlatIndexerProcessor;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
+     */
+    protected $_productPriceIndexerProcessor;
+
+    /**
+     * Catalog product
+     *
+     * @var \Magento\Catalog\Helper\Product
+     */
+    protected $_catalogProduct;
+
+    /**
+     * @var \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder
+     */
+    protected $stockItemBuilder;
+
+    /**
+     * Stock Indexer
+     *
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_stockIndexerProcessor;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeHelper
+     * @param \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor
+     * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor
+     * @param \Magento\Catalog\Helper\Product $catalogProduct
+     * @param \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Catalog\Helper\Product\Edit\Action\Attribute $attributeHelper,
+        \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
+        \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor,
+        \Magento\Catalog\Helper\Product $catalogProduct,
+        \Magento\CatalogInventory\Service\V1\Data\StockItemBuilder $stockItemBuilder
+    ) {
+        $this->_productFlatIndexerProcessor = $productFlatIndexerProcessor;
+        $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
+        $this->_stockIndexerProcessor = $stockIndexerProcessor;
+        $this->_catalogProduct = $catalogProduct;
+        $this->stockItemBuilder = $stockItemBuilder;
+        parent::__construct($context, $attributeHelper);
+    }
+
+    /**
+     * Update product attributes
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateProducts()) {
+            return;
+        }
+
+        /* Collect Data */
+        $inventoryData = $this->getRequest()->getParam('inventory', array());
+        $attributesData = $this->getRequest()->getParam('attributes', array());
+        $websiteRemoveData = $this->getRequest()->getParam('remove_website_ids', array());
+        $websiteAddData = $this->getRequest()->getParam('add_website_ids', array());
+
+        /* Prepare inventory data item options (use config settings) */
+        $options = $this->_objectManager->get('Magento\CatalogInventory\Helper\Data')->getConfigItemOptions();
+        foreach ($options as $option) {
+            if (isset($inventoryData[$option]) && !isset($inventoryData['use_config_' . $option])) {
+                $inventoryData['use_config_' . $option] = 0;
+            }
+        }
+
+        try {
+            if ($attributesData) {
+                $dateFormat = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface')
+                    ->getDateFormat(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_SHORT);
+                $storeId = $this->attributeHelper->getSelectedStoreId();
+
+                foreach ($attributesData as $attributeCode => $value) {
+                    $attribute = $this->_objectManager->get('Magento\Eav\Model\Config')
+                        ->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode);
+                    if (!$attribute->getAttributeId()) {
+                        unset($attributesData[$attributeCode]);
+                        continue;
+                    }
+                    if ($attribute->getBackendType() == 'datetime') {
+                        if (!empty($value)) {
+                            $filterInput = new \Zend_Filter_LocalizedToNormalized(array('date_format' => $dateFormat));
+                            $filterInternal = new \Zend_Filter_NormalizedToLocalized(
+                                array('date_format' => \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT)
+                            );
+                            $value = $filterInternal->filter($filterInput->filter($value));
+                        } else {
+                            $value = null;
+                        }
+                        $attributesData[$attributeCode] = $value;
+                    } elseif ($attribute->getFrontendInput() == 'multiselect') {
+                        // Check if 'Change' checkbox has been checked by admin for this attribute
+                        $isChanged = (bool) $this->getRequest()->getPost($attributeCode . '_checkbox');
+                        if (!$isChanged) {
+                            unset($attributesData[$attributeCode]);
+                            continue;
+                        }
+                        if (is_array($value)) {
+                            $value = implode(',', $value);
+                        }
+                        $attributesData[$attributeCode] = $value;
+                    }
+                }
+
+                $this->_objectManager->get('Magento\Catalog\Model\Product\Action')
+                    ->updateAttributes($this->attributeHelper->getProductIds(), $attributesData, $storeId);
+            }
+
+            if ($inventoryData) {
+                /** @var \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService */
+                $stockItemService = $this->_objectManager
+                    ->create('Magento\CatalogInventory\Service\V1\StockItemService');
+
+                foreach ($this->_helper->getProductIds() as $productId) {
+                    $stockItemDo = $stockItemService->getStockItem($productId);
+                    if (!$stockItemDo->getProductId()) {
+                        $inventoryData[] = $productId;
+                    }
+
+                    $stockItemService->saveStockItem(
+                        $this->stockItemBuilder->mergeDataObjectWithArray($stockItemDo, $inventoryData)
+                    );
+                }
+                $this->_stockIndexerProcessor->reindexList($this->_helper->getProductIds());
+            }
+
+            if ($websiteAddData || $websiteRemoveData) {
+                /* @var $actionModel \Magento\Catalog\Model\Product\Action */
+                $actionModel = $this->_objectManager->get('Magento\Catalog\Model\Product\Action');
+                $productIds = $this->attributeHelper->getProductIds();
+
+                if ($websiteRemoveData) {
+                    $actionModel->updateWebsites($productIds, $websiteRemoveData, 'remove');
+                }
+                if ($websiteAddData) {
+                    $actionModel->updateWebsites($productIds, $websiteAddData, 'add');
+                }
+
+                $this->_eventManager->dispatch('catalog_product_to_website_change', array('products' => $productIds));
+
+                $this->messageManager->addNotice(
+                    __(
+                        'Please refresh "Catalog URL Rewrites" and "Product Attributes" in System -> ' .
+                        '<a href="%1">Index Management</a>.',
+                        $this->getUrl('adminhtml/process/list')
+                    )
+                );
+            }
+
+            $this->messageManager->addSuccess(
+                __('A total of %1 record(s) were updated.', count($this->attributeHelper->getProductIds()))
+            );
+
+            $this->_productFlatIndexerProcessor->reindexList($this->attributeHelper->getProductIds());
+
+            if ($this->_catalogProduct->isDataForPriceIndexerWasChanged($attributesData)
+                || !empty($websiteRemoveData)
+                || !empty($websiteAddData)
+            ) {
+                $this->_productPriceIndexerProcessor->reindexList($this->attributeHelper->getProductIds());
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException(
+                $e,
+                __('Something went wrong while updating the product(s) attributes.')
+            );
+        }
+
+        $this->_redirect('catalog/product/', array('store' => $this->attributeHelper->getSelectedStoreId()));
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee694c55342a8781ec3cdfab4ca26ab813dbc4ab
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Action/Attribute/Validate.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute;
+
+class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Action\Attribute
+{
+    /**
+     * Attributes validation action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(false);
+        $attributesData = $this->getRequest()->getParam('attributes', array());
+        $data = new \Magento\Framework\Object();
+
+        try {
+            if ($attributesData) {
+                foreach ($attributesData as $attributeCode => $value) {
+                    $attribute = $this->_objectManager->get('Magento\Eav\Model\Config')
+                        ->getAttribute('catalog_product', $attributeCode);
+                    if (!$attribute->getAttributeId()) {
+                        unset($attributesData[$attributeCode]);
+                        continue;
+                    }
+                    $data->setData($attributeCode, $value);
+                    $attribute->getBackend()->validate($data);
+                }
+            }
+        } catch (\Magento\Eav\Model\Entity\Attribute\Exception $e) {
+            $response->setError(true);
+            $response->setAttribute($e->getAttributeCode());
+            $response->setMessage($e->getMessage());
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response->setError(true);
+            $response->setMessage($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException(
+                $e,
+                __('Something went wrong while updating the product(s) attributes.')
+            );
+            $this->_view->getLayout()->initMessages();
+            $response->setError(true);
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php
new file mode 100644
index 0000000000000000000000000000000000000000..34a46d46aabdb047a28f16e3466f6647a18bb8f4
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AddAttributeToTemplate.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Add attribute to product template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+        try {
+            /** @var \Magento\Eav\Model\Entity\Attribute $attribute */
+            $attribute = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute')
+                ->load($request->getParam('attribute_id'));
+
+            $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')
+                ->load($request->getParam('template_id'));
+
+            /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection $attributeGroupCollection */
+            $attributeGroupCollection = $this->_objectManager->get(
+                'Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection'
+            );
+            $attributeGroupCollection->setAttributeSetFilter($attributeSet->getId());
+            $attributeGroupCollection->addFilter('attribute_group_code', $request->getParam('group'));
+            $attributeGroupCollection->setPageSize(1);
+
+            $attributeGroup = $attributeGroupCollection->getFirstItem();
+
+            $attribute->setAttributeSetId($attributeSet->getId())->loadEntityAttributeIdBySet();
+
+            $attribute->setEntityTypeId($attributeSet->getEntityTypeId())
+                ->setAttributeSetId($request->getParam('template_id'))
+                ->setAttributeGroupId($attributeGroup->getId())
+                ->setSortOrder('0')
+                ->save();
+
+            $this->getResponse()->representJson($attribute->toJson());
+        } catch (\Exception $e) {
+            $response = new \Magento\Framework\Object();
+            $response->setError(false);
+            $response->setMessage($e->getMessage());
+            $this->getResponse()->representJson($response->toJson());
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsPriceGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsPriceGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2e1ee921ca1afb3b56475feda6d9f723c6e9df5
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsPriceGrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class AlertsPriceGrid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get alerts price grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsStockGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsStockGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..1585f372958a042af698bf0fe06c92ff72048a23
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/AlertsStockGrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class AlertsStockGrid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get alerts stock grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php
index e4806b7a9fb43d80781ca4dff9a22ae117af1730..116a8a79ffc8e35e61fca21b1c00e5fa7831fa3e 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute.php
@@ -32,7 +32,7 @@ class Attribute extends \Magento\Backend\App\Action
     /**
      * @var \Magento\Framework\Cache\FrontendInterface
      */
-    private $_attributeLabelCache;
+    protected $_attributeLabelCache;
 
     /**
      * @var string
@@ -109,136 +109,13 @@ class Attribute extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_initAction()->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Product\Attribute')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $id = $this->getRequest()->getParam('attribute_id');
-        /** @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */
-        $model = $this->_objectManager->create(
-            'Magento\Catalog\Model\Resource\Eav\Attribute'
-        )->setEntityTypeId(
-            $this->_entityTypeId
-        );
-        if ($id) {
-            $model->load($id);
-
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This attribute no longer exists.'));
-                $this->_redirect('catalog/*/');
-                return;
-            }
-
-            // entity type check
-            if ($model->getEntityTypeId() != $this->_entityTypeId) {
-                $this->messageManager->addError(__('This attribute cannot be edited.'));
-                $this->_redirect('catalog/*/');
-                return;
-            }
-        }
-
-        // set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getAttributeData(true);
-        if (!empty($data)) {
-            $model->addData($data);
-        }
-        $attributeData = $this->getRequest()->getParam('attribute');
-        if (!empty($attributeData) && $id === null) {
-            $model->addData($attributeData);
-        }
-
-        $this->_coreRegistry->register('entity_attribute', $model);
-
-        $this->_initAction();
-
-        $this->_title->add($id ? $model->getName() : __('New Product Attribute'));
-
-        $item = $id ? __('Edit Product Attribute') : __('New Product Attribute');
-
-        $this->_addBreadcrumb($item, $item);
-
-        $this->_view->getLayout()->getBlock(
-            'attribute_edit_js'
-        )->setIsPopup(
-            (bool)$this->getRequest()->getParam('popup')
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(false);
-
-        $attributeCode = $this->getRequest()->getParam('attribute_code');
-        $frontendLabel = $this->getRequest()->getParam('frontend_label');
-        $attributeCode = $attributeCode ?: $this->generateCode($frontendLabel[0]);
-        $attributeId = $this->getRequest()->getParam('attribute_id');
-        $attribute = $this->_objectManager->create(
-            'Magento\Catalog\Model\Resource\Eav\Attribute'
-        )->loadByCode(
-            $this->_entityTypeId,
-            $attributeCode
-        );
-
-        if ($attribute->getId() && !$attributeId) {
-            if (strlen($this->getRequest()->getParam('attribute_code'))) {
-                $response->setAttributes(array('attribute_code' => __('An attribute with this code already exists.')));
-            } else {
-                $response->setAttributes(
-                    array('attribute_label' => __('Attribute with the same code (%1) already exists.', $attributeCode))
-                );
-            }
-            $response->setError(true);
-        }
-        if ($this->getRequest()->has('new_attribute_set_name')) {
-            $setName = $this->getRequest()->getParam('new_attribute_set_name');
-            /** @var $attributeSet \Magento\Eav\Model\Entity\Attribute\Set */
-            $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set');
-            $attributeSet->setEntityTypeId($this->_entityTypeId)->load($setName, 'attribute_set_name');
-            if ($attributeSet->getId()) {
-                $setName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($setName);
-                $this->messageManager->addError(__('Attribute Set with name \'%1\' already exists.', $setName));
-
-                $this->_view->getLayout()->initMessages();
-                $response->setError(true);
-                $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-            }
-        }
-        $this->getResponse()->representJson($response->toJson());
-    }
-
     /**
      * Generate code from label
      *
      * @param string $label
      * @return string
      */
-    private function generateCode($label)
+    protected function generateCode($label)
     {
         $code = substr(
             preg_replace(
@@ -256,225 +133,6 @@ class Attribute extends \Magento\Backend\App\Action
         return $code;
     }
 
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            /** @var $session \Magento\Backend\Model\Auth\Session */
-            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-
-            $isNewAttributeSet = false;
-            if (!empty($data['new_attribute_set_name'])) {
-                /** @var $attributeSet \Magento\Eav\Model\Entity\Attribute\Set */
-                $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set');
-                $name = $this->_objectManager->get(
-                    'Magento\Framework\Filter\FilterManager'
-                )->stripTags(
-                    $data['new_attribute_set_name']
-                );
-                $name = trim($name);
-                $attributeSet->setEntityTypeId($this->_entityTypeId)->load($name, 'attribute_set_name');
-
-                if ($attributeSet->getId()) {
-                    $this->messageManager->addError(__('Attribute Set with name \'%1\' already exists.', $name));
-                    $this->messageManager->setAttributeData($data);
-                    $this->_redirect('catalog/*/edit', array('_current' => true));
-                    return;
-                }
-
-                try {
-                    $attributeSet->setAttributeSetName($name)->validate();
-                    $attributeSet->save();
-                    $attributeSet->initFromSkeleton($this->getRequest()->getParam('set'))->save();
-                    $isNewAttributeSet = true;
-                } catch (\Magento\Framework\Model\Exception $e) {
-                    $this->messageManager->addError($e->getMessage());
-                } catch (\Exception $e) {
-                    $this->messageManager->addException($e, __('Something went wrong saving the attribute.'));
-                }
-            }
-
-            $redirectBack = $this->getRequest()->getParam('back', false);
-            /* @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */
-            $model = $this->_objectManager->create('Magento\Catalog\Model\Resource\Eav\Attribute');
-            /* @var $helper \Magento\Catalog\Helper\Product */
-            $helper = $this->_objectManager->get('Magento\Catalog\Helper\Product');
-
-            $id = $this->getRequest()->getParam('attribute_id');
-
-            $attributeCode = $this->getRequest()->getParam('attribute_code');
-            $frontendLabel = $this->getRequest()->getParam('frontend_label');
-            $attributeCode = $attributeCode ?: $this->generateCode($frontendLabel[0]);
-            if (strlen($this->getRequest()->getParam('attribute_code')) > 0) {
-                $validatorAttrCode = new \Zend_Validate_Regex(array('pattern' => '/^[a-z][a-z_0-9]{0,30}$/'));
-                if (!$validatorAttrCode->isValid($attributeCode)) {
-                    $this->messageManager->addError(
-                        __(
-                            'Attribute code "%1" is invalid. Please use only letters (a-z), ' .
-                            'numbers (0-9) or underscore(_) in this field, first character should be a letter.',
-                            $attributeCode
-                        )
-                    );
-                    $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
-                    return;
-                }
-            }
-            $data['attribute_code'] = $attributeCode;
-
-            //validate frontend_input
-            if (isset($data['frontend_input'])) {
-                /** @var $inputType \Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator */
-                $inputType = $this->_objectManager->create(
-                    'Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator'
-                );
-                if (!$inputType->isValid($data['frontend_input'])) {
-                    foreach ($inputType->getMessages() as $message) {
-                        $this->messageManager->addError($message);
-                    }
-                    $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
-                    return;
-                }
-            }
-
-            if ($id) {
-                $model->load($id);
-                if (!$model->getId()) {
-                    $this->messageManager->addError(__('This attribute no longer exists.'));
-                    $this->_redirect('catalog/*/');
-                    return;
-                }
-                // entity type check
-                if ($model->getEntityTypeId() != $this->_entityTypeId) {
-                    $this->messageManager->addError(__('You can\'t update your attribute.'));
-                    $session->setAttributeData($data);
-                    $this->_redirect('catalog/*/');
-                    return;
-                }
-
-                $data['attribute_code'] = $model->getAttributeCode();
-                $data['is_user_defined'] = $model->getIsUserDefined();
-                $data['frontend_input'] = $model->getFrontendInput();
-            } else {
-                /**
-                 * @todo add to helper and specify all relations for properties
-                 */
-                $data['source_model'] = $helper->getAttributeSourceModelByInputType($data['frontend_input']);
-                $data['backend_model'] = $helper->getAttributeBackendModelByInputType($data['frontend_input']);
-            }
-
-            $data += array('is_filterable' => 0, 'is_filterable_in_search' => 0, 'apply_to' => array());
-
-            if (is_null($model->getIsUserDefined()) || $model->getIsUserDefined() != 0) {
-                $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']);
-            }
-
-            $defaultValueField = $model->getDefaultValueByInput($data['frontend_input']);
-            if ($defaultValueField) {
-                $data['default_value'] = $this->getRequest()->getParam($defaultValueField);
-            }
-
-            if (!$model->getIsUserDefined() && $model->getId()) {
-                // Unset attribute field for system attributes
-                unset($data['apply_to']);
-            }
-
-            $model->addData($data);
-
-            if (!$id) {
-                $model->setEntityTypeId($this->_entityTypeId);
-                $model->setIsUserDefined(1);
-            }
-
-            $groupCode = $this->getRequest()->getParam('group');
-            if ($this->getRequest()->getParam('set') && $groupCode) {
-                // For creating product attribute on product page we need specify attribute set and group
-                $attributeSetId = $isNewAttributeSet ? $attributeSet->getId() : $this->getRequest()->getParam('set');
-                $groupCollection = $isNewAttributeSet ? $attributeSet->getGroups() : $this->_objectManager->create(
-                    'Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection'
-                )->setAttributeSetFilter(
-                    $attributeSetId
-                )->load();
-                foreach ($groupCollection as $group) {
-                    if ($group->getAttributeGroupCode() == $groupCode) {
-                        $attributeGroupId = $group->getAttributeGroupId();
-                        break;
-                    }
-                }
-                $model->setAttributeSetId($attributeSetId);
-                $model->setAttributeGroupId($attributeGroupId);
-            }
-
-            try {
-                $model->save();
-                $this->messageManager->addSuccess(__('You saved the product attribute.'));
-
-                $this->_attributeLabelCache->clean();
-                $session->setAttributeData(false);
-                if ($this->getRequest()->getParam('popup')) {
-                    $requestParams = array(
-                        'id' => $this->getRequest()->getParam('product'),
-                        'attribute' => $model->getId(),
-                        '_current' => true,
-                        'product_tab' => $this->getRequest()->getParam('product_tab')
-                    );
-                    if ($isNewAttributeSet) {
-                        $requestParams['new_attribute_set_id'] = $attributeSet->getId();
-                    }
-                    $this->_redirect('catalog/product/addAttribute', $requestParams);
-                } elseif ($redirectBack) {
-                    $this->_redirect('catalog/*/edit', array('attribute_id' => $model->getId(), '_current' => true));
-                } else {
-                    $this->_redirect('catalog/*/', array());
-                }
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $session->setAttributeData($data);
-                $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
-                return;
-            }
-        }
-        $this->_redirect('catalog/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('attribute_id');
-        if ($id) {
-            $model = $this->_objectManager->create('Magento\Catalog\Model\Resource\Eav\Attribute');
-
-            // entity type check
-            $model->load($id);
-            if ($model->getEntityTypeId() != $this->_entityTypeId) {
-                $this->messageManager->addError(__('This attribute cannot be deleted.'));
-                $this->_redirect('catalog/*/');
-                return;
-            }
-
-            try {
-                $model->delete();
-                $this->messageManager->addSuccess(__('The product attribute has been deleted.'));
-                $this->_redirect('catalog/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect(
-                    'catalog/*/edit',
-                    array('attribute_id' => $this->getRequest()->getParam('attribute_id'))
-                );
-                return;
-            }
-        }
-        $this->messageManager->addError(__('We can\'t find an attribute to delete.'));
-        $this->_redirect('catalog/*/');
-    }
-
     /**
      * ACL check
      *
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Delete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..5ba8135f0263ddfbc425392cfe46209e3460c2f0
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Delete.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class Delete extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('attribute_id');
+        if ($id) {
+            $model = $this->_objectManager->create('Magento\Catalog\Model\Resource\Eav\Attribute');
+
+            // entity type check
+            $model->load($id);
+            if ($model->getEntityTypeId() != $this->_entityTypeId) {
+                $this->messageManager->addError(__('This attribute cannot be deleted.'));
+                $this->_redirect('catalog/*/');
+                return;
+            }
+
+            try {
+                $model->delete();
+                $this->messageManager->addSuccess(__('The product attribute has been deleted.'));
+                $this->_redirect('catalog/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect(
+                    'catalog/*/edit',
+                    array('attribute_id' => $this->getRequest()->getParam('attribute_id'))
+                );
+                return;
+            }
+        }
+        $this->messageManager->addError(__('We can\'t find an attribute to delete.'));
+        $this->_redirect('catalog/*/');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..883d85470bb0203025b77dedd843551c62f06c8b
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Edit.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('attribute_id');
+        /** @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */
+        $model = $this->_objectManager->create(
+            'Magento\Catalog\Model\Resource\Eav\Attribute'
+        )->setEntityTypeId(
+            $this->_entityTypeId
+        );
+        if ($id) {
+            $model->load($id);
+
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This attribute no longer exists.'));
+                $this->_redirect('catalog/*/');
+                return;
+            }
+
+            // entity type check
+            if ($model->getEntityTypeId() != $this->_entityTypeId) {
+                $this->messageManager->addError(__('This attribute cannot be edited.'));
+                $this->_redirect('catalog/*/');
+                return;
+            }
+        }
+
+        // set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getAttributeData(true);
+        if (!empty($data)) {
+            $model->addData($data);
+        }
+        $attributeData = $this->getRequest()->getParam('attribute');
+        if (!empty($attributeData) && $id === null) {
+            $model->addData($attributeData);
+        }
+
+        $this->_coreRegistry->register('entity_attribute', $model);
+
+        $this->_initAction();
+
+        $this->_title->add($id ? $model->getName() : __('New Product Attribute'));
+
+        $item = $id ? __('Edit Product Attribute') : __('New Product Attribute');
+
+        $this->_addBreadcrumb($item, $item);
+
+        $this->_view->getLayout()->getBlock(
+            'attribute_edit_js'
+        )->setIsPopup(
+            (bool)$this->getRequest()->getParam('popup')
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7bd0bad0ab4d5182cd5e522c59f2b569d0726476
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initAction()->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Product\Attribute')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..694f4dd33b31d3bd34bac08bd6755563d962e7ea
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..17bf2e992c3bd3a8c5ef00888bf4850c39bd7f67
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Save.php
@@ -0,0 +1,212 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            /** @var $session \Magento\Backend\Model\Auth\Session */
+            $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+
+            $isNewAttributeSet = false;
+            if (!empty($data['new_attribute_set_name'])) {
+                /** @var $attributeSet \Magento\Eav\Model\Entity\Attribute\Set */
+                $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set');
+                $name = $this->_objectManager->get(
+                    'Magento\Framework\Filter\FilterManager'
+                )->stripTags(
+                    $data['new_attribute_set_name']
+                );
+                $name = trim($name);
+                $attributeSet->setEntityTypeId($this->_entityTypeId)->load($name, 'attribute_set_name');
+
+                if ($attributeSet->getId()) {
+                    $this->messageManager->addError(__('Attribute Set with name \'%1\' already exists.', $name));
+                    $this->messageManager->setAttributeData($data);
+                    $this->_redirect('catalog/*/edit', array('_current' => true));
+                    return;
+                }
+
+                try {
+                    $attributeSet->setAttributeSetName($name)->validate();
+                    $attributeSet->save();
+                    $attributeSet->initFromSkeleton($this->getRequest()->getParam('set'))->save();
+                    $isNewAttributeSet = true;
+                } catch (\Magento\Framework\Model\Exception $e) {
+                    $this->messageManager->addError($e->getMessage());
+                } catch (\Exception $e) {
+                    $this->messageManager->addException($e, __('Something went wrong saving the attribute.'));
+                }
+            }
+
+            $redirectBack = $this->getRequest()->getParam('back', false);
+            /* @var $model \Magento\Catalog\Model\Resource\Eav\Attribute */
+            $model = $this->_objectManager->create('Magento\Catalog\Model\Resource\Eav\Attribute');
+            /* @var $helper \Magento\Catalog\Helper\Product */
+            $helper = $this->_objectManager->get('Magento\Catalog\Helper\Product');
+
+            $id = $this->getRequest()->getParam('attribute_id');
+
+            $attributeCode = $this->getRequest()->getParam('attribute_code');
+            $frontendLabel = $this->getRequest()->getParam('frontend_label');
+            $attributeCode = $attributeCode ?: $this->generateCode($frontendLabel[0]);
+            if (strlen($this->getRequest()->getParam('attribute_code')) > 0) {
+                $validatorAttrCode = new \Zend_Validate_Regex(array('pattern' => '/^[a-z][a-z_0-9]{0,30}$/'));
+                if (!$validatorAttrCode->isValid($attributeCode)) {
+                    $this->messageManager->addError(
+                        __(
+                            'Attribute code "%1" is invalid. Please use only letters (a-z), ' .
+                            'numbers (0-9) or underscore(_) in this field, first character should be a letter.',
+                            $attributeCode
+                        )
+                    );
+                    $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
+                    return;
+                }
+            }
+            $data['attribute_code'] = $attributeCode;
+
+            //validate frontend_input
+            if (isset($data['frontend_input'])) {
+                /** @var $inputType \Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator */
+                $inputType = $this->_objectManager->create(
+                    'Magento\Eav\Model\Adminhtml\System\Config\Source\Inputtype\Validator'
+                );
+                if (!$inputType->isValid($data['frontend_input'])) {
+                    foreach ($inputType->getMessages() as $message) {
+                        $this->messageManager->addError($message);
+                    }
+                    $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
+                    return;
+                }
+            }
+
+            if ($id) {
+                $model->load($id);
+                if (!$model->getId()) {
+                    $this->messageManager->addError(__('This attribute no longer exists.'));
+                    $this->_redirect('catalog/*/');
+                    return;
+                }
+                // entity type check
+                if ($model->getEntityTypeId() != $this->_entityTypeId) {
+                    $this->messageManager->addError(__('You can\'t update your attribute.'));
+                    $session->setAttributeData($data);
+                    $this->_redirect('catalog/*/');
+                    return;
+                }
+
+                $data['attribute_code'] = $model->getAttributeCode();
+                $data['is_user_defined'] = $model->getIsUserDefined();
+                $data['frontend_input'] = $model->getFrontendInput();
+            } else {
+                /**
+                 * @todo add to helper and specify all relations for properties
+                 */
+                $data['source_model'] = $helper->getAttributeSourceModelByInputType($data['frontend_input']);
+                $data['backend_model'] = $helper->getAttributeBackendModelByInputType($data['frontend_input']);
+            }
+
+            $data += array('is_filterable' => 0, 'is_filterable_in_search' => 0, 'apply_to' => array());
+
+            if (is_null($model->getIsUserDefined()) || $model->getIsUserDefined() != 0) {
+                $data['backend_type'] = $model->getBackendTypeByInput($data['frontend_input']);
+            }
+
+            $defaultValueField = $model->getDefaultValueByInput($data['frontend_input']);
+            if ($defaultValueField) {
+                $data['default_value'] = $this->getRequest()->getParam($defaultValueField);
+            }
+
+            if (!$model->getIsUserDefined() && $model->getId()) {
+                // Unset attribute field for system attributes
+                unset($data['apply_to']);
+            }
+
+            $model->addData($data);
+
+            if (!$id) {
+                $model->setEntityTypeId($this->_entityTypeId);
+                $model->setIsUserDefined(1);
+            }
+
+            $groupCode = $this->getRequest()->getParam('group');
+            if ($this->getRequest()->getParam('set') && $groupCode) {
+                // For creating product attribute on product page we need specify attribute set and group
+                $attributeSetId = $isNewAttributeSet ? $attributeSet->getId() : $this->getRequest()->getParam('set');
+                $groupCollection = $isNewAttributeSet ? $attributeSet->getGroups() : $this->_objectManager->create(
+                    'Magento\Eav\Model\Resource\Entity\Attribute\Group\Collection'
+                )->setAttributeSetFilter(
+                    $attributeSetId
+                )->load();
+                foreach ($groupCollection as $group) {
+                    if ($group->getAttributeGroupCode() == $groupCode) {
+                        $attributeGroupId = $group->getAttributeGroupId();
+                        break;
+                    }
+                }
+                $model->setAttributeSetId($attributeSetId);
+                $model->setAttributeGroupId($attributeGroupId);
+            }
+
+            try {
+                $model->save();
+                $this->messageManager->addSuccess(__('You saved the product attribute.'));
+
+                $this->_attributeLabelCache->clean();
+                $session->setAttributeData(false);
+                if ($this->getRequest()->getParam('popup')) {
+                    $requestParams = array(
+                        'id' => $this->getRequest()->getParam('product'),
+                        'attribute' => $model->getId(),
+                        '_current' => true,
+                        'product_tab' => $this->getRequest()->getParam('product_tab')
+                    );
+                    if ($isNewAttributeSet) {
+                        $requestParams['new_attribute_set_id'] = $attributeSet->getId();
+                    }
+                    $this->_redirect('catalog/product/addAttribute', $requestParams);
+                } elseif ($redirectBack) {
+                    $this->_redirect('catalog/*/edit', array('attribute_id' => $model->getId(), '_current' => true));
+                } else {
+                    $this->_redirect('catalog/*/', array());
+                }
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $session->setAttributeData($data);
+                $this->_redirect('catalog/*/edit', array('attribute_id' => $id, '_current' => true));
+                return;
+            }
+        }
+        $this->_redirect('catalog/*/');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..e337e787c00fa32cbf79610ab3f713f96c5c3faa
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Attribute/Validate.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Attribute;
+
+class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Attribute
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(false);
+
+        $attributeCode = $this->getRequest()->getParam('attribute_code');
+        $frontendLabel = $this->getRequest()->getParam('frontend_label');
+        $attributeCode = $attributeCode ?: $this->generateCode($frontendLabel[0]);
+        $attributeId = $this->getRequest()->getParam('attribute_id');
+        $attribute = $this->_objectManager->create(
+            'Magento\Catalog\Model\Resource\Eav\Attribute'
+        )->loadByCode(
+            $this->_entityTypeId,
+            $attributeCode
+        );
+
+        if ($attribute->getId() && !$attributeId) {
+            if (strlen($this->getRequest()->getParam('attribute_code'))) {
+                $response->setAttributes(array('attribute_code' => __('An attribute with this code already exists.')));
+            } else {
+                $response->setAttributes(
+                    array('attribute_label' => __('Attribute with the same code (%1) already exists.', $attributeCode))
+                );
+            }
+            $response->setError(true);
+        }
+        if ($this->getRequest()->has('new_attribute_set_name')) {
+            $setName = $this->getRequest()->getParam('new_attribute_set_name');
+            /** @var $attributeSet \Magento\Eav\Model\Entity\Attribute\Set */
+            $attributeSet = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set');
+            $attributeSet->setEntityTypeId($this->_entityTypeId)->load($setName, 'attribute_set_name');
+            if ($attributeSet->getId()) {
+                $setName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($setName);
+                $this->messageManager->addError(__('Attribute Set with name \'%1\' already exists.', $setName));
+
+                $this->_view->getLayout()->initMessages();
+                $response->setError(true);
+                $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+            }
+        }
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
index 126cbb066a802c028a2aad61a991d94f72c3a96c..0265f90e5f35f3e839afa87f6f7fa01206bc85ee 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Builder.php
@@ -26,7 +26,7 @@ namespace Magento\Catalog\Controller\Adminhtml\Product;
 
 use Magento\Framework\App\RequestInterface;
 use Magento\Catalog\Model\ProductFactory;
-use Magento\Cms\Model\Wysiwyg;
+use Magento\Cms\Model\Wysiwyg as WysiwygModel;
 use Magento\Framework\Registry;
 use Magento\Framework\Logger;
 
@@ -56,13 +56,13 @@ class Builder
      * @param ProductFactory $productFactory
      * @param Logger $logger
      * @param Registry $registry
-     * @param Wysiwyg\Config $wysiwygConfig
+     * @param WysiwygModel\Config $wysiwygConfig
      */
     public function __construct(
         ProductFactory $productFactory,
         Logger $logger,
         Registry $registry,
-        Wysiwyg\Config $wysiwygConfig
+        WysiwygModel\Config $wysiwygConfig
     ) {
         $this->productFactory = $productFactory;
         $this->logger = $logger;
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Categories.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Categories.php
new file mode 100644
index 0000000000000000000000000000000000000000..1873182c891d30399986014edfd25a1a0d8d70c3
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Categories.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Categories extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get categories fieldset block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Crosssell.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Crosssell.php
new file mode 100644
index 0000000000000000000000000000000000000000..018e204207fe58802143d8f759a600595efd2ba1
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Crosssell.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Crosssell extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get crosssell products grid and serializer block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.crosssell')
+            ->setProductsCrossSell($this->getRequest()->getPost('products_crosssell', null));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/CrosssellGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/CrosssellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..22aa08f5ea9aa958978295ad04051b440cace6d8
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/CrosssellGrid.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class CrosssellGrid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get crosssell products grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.crosssell')
+            ->setProductsRelated($this->getRequest()->getPost('products_crosssell', null));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/CustomOptions.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/CustomOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..e94051322021f8706b9b1341a6e7f364efcf4933
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/CustomOptions.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class CustomOptions extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->registry = $registry;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * Show custom options in JSON format for specified products
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->registry->register('import_option_products', $this->getRequest()->getPost('products'));
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..e116db630827ceb55f51c973723db511971a910b
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds/Index.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Datafeeds;
+
+class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2f7345b4f784c777597312de59e92fc5239443d
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Duplicate.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class Duplicate extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var \Magento\Catalog\Model\Product\Copier
+     */
+    protected $productCopier;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param \Magento\Catalog\Model\Product\Copier $productCopier
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        \Magento\Catalog\Model\Product\Copier $productCopier
+    ) {
+        $this->productCopier = $productCopier;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * Create product duplicate
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $product = $this->productBuilder->build($this->getRequest());
+        try {
+            $newProduct = $this->productCopier->copy($product);
+            $this->messageManager->addSuccess(__('You duplicated the product.'));
+            $this->_redirect('catalog/*/edit', array('_current' => true, 'id' => $newProduct->getId()));
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('catalog/*/edit', array('_current' => true));
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..a14533d546c0609b22a6bd5cbf5ef9b0738d1b08
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Edit.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+
+    /**
+     * Array of actions which can be processed without secret key validation
+     *
+     * @var array
+     */
+    protected $_publicActions = array('edit');
+
+    /**
+     * Product edit form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Products'));
+        $productId = (int) $this->getRequest()->getParam('id');
+        $product = $this->productBuilder->build($this->getRequest());
+
+        if ($productId && !$product->getId()) {
+            $this->messageManager->addError(__('This product no longer exists.'));
+            $this->_redirect('catalog/*/');
+            return;
+        }
+
+        $this->_title->add($product->getName());
+
+        $this->_eventManager->dispatch('catalog_product_edit_action', array('product' => $product));
+
+        $this->_view->loadLayout(
+            array(
+                'default',
+                strtolower($this->_request->getFullActionName()),
+                'catalog_product_' . $product->getTypeId()
+            )
+        );
+
+        $this->_setActiveMenu('Magento_Catalog::catalog_products');
+
+        if (!$this->_objectManager->get(
+            'Magento\Store\Model\StoreManagerInterface'
+        )->isSingleStoreMode() && ($switchBlock = $this->_view->getLayout()->getBlock(
+            'store_switcher'
+        ))
+        ) {
+            $switchBlock->setDefaultStoreName(__('Default Values'))
+                ->setWebsiteIds($product->getWebsiteIds())
+                ->setSwitchUrl(
+                    $this->getUrl(
+                        'catalog/*/*',
+                        array('_current' => true, 'active_tab' => null, 'tab' => null, 'store' => null)
+                    )
+                );
+        }
+
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
+        if ($block) {
+            $block->setStoreId($product->getStoreId());
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php
similarity index 92%
rename from app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php
rename to app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php
index a8a3f1f448bf0409380876f1e8363ca97d37aee4..c306c98005840076b8a6c39649d8c24d48fba4c0 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Gallery/Upload.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,19 +22,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller\Adminhtml\Product;
+namespace Magento\Catalog\Controller\Adminhtml\Product\Gallery;
 
-/**
- * Catalog product gallery controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Gallery extends \Magento\Backend\App\Action
+class Upload extends \Magento\Backend\App\Action
 {
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Catalog::products');
+    }
+
     /**
      * @return void
      */
-    public function uploadAction()
+    public function execute()
     {
         try {
             $uploader = $this->_objectManager->create('Magento\Core\Model\File\Uploader', array('fileId' => 'image'));
@@ -74,12 +78,4 @@ class Gallery extends \Magento\Backend\App\Action
             $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
         );
     }
-
-    /**
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Catalog::products');
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Grid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..b94c6bdb3419f93682133fc3e4a5f907acb288d2
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Grid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Product grid for AJAX request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ec4165a4a36296070700afe33d3f6219c972b46
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/GridOnly.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class GridOnly extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get specified tab grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Products'));
+
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+
+        $block = $this->getRequest()->getParam('gridOnlyBlock');
+        $blockClassSuffix = str_replace(' ', '_', ucwords(str_replace('_', ' ', $block)));
+
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\\' . $blockClassSuffix
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Group.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Group/Save.php
similarity index 92%
rename from app/code/Magento/Catalog/Controller/Adminhtml/Product/Group.php
rename to app/code/Magento/Catalog/Controller/Adminhtml/Product/Group/Save.php
index 21df4b7d3ed2f9c19e843176cfa3e265935b114b..cc5bf550f8b345bf71ab3c96820dd63c6ce9f909 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Group.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Group/Save.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller\Adminhtml\Product;
+namespace Magento\Catalog\Controller\Adminhtml\Product\Group;
 
-class Group extends \Magento\Backend\App\Action
+class Save extends \Magento\Backend\App\Action
 {
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Catalog::products');
+    }
+
     /**
      * @return void
      */
-    public function saveAction()
+    public function execute()
     {
         $model = $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Group');
 
@@ -48,12 +57,4 @@ class Group extends \Magento\Backend\App\Action
             }
         }
     }
-
-    /**
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Catalog::products');
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf26ec6ee1c9a96f7074a4dae080ff8508e1a432
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Product list page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Products'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_products');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassDelete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e33ba33473d1f4ebfe0af687b1d332c335d40a3
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassDelete.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $productIds = $this->getRequest()->getParam('product');
+        if (!is_array($productIds) || empty($productIds)) {
+            $this->messageManager->addError(__('Please select product(s).'));
+        } else {
+            try {
+                foreach ($productIds as $productId) {
+                    $product = $this->_objectManager->get('Magento\Catalog\Model\Product')->load($productId);
+                    $product->delete();
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 record(s) have been deleted.', count($productIds))
+                );
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+        $this->_redirect('catalog/*/index');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b7fc6a31a88382fb78067ee966b324fb1e54ab1
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/MassStatus.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
+     */
+    protected $_productPriceIndexerProcessor;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor
+    ) {
+        $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * Validate batch of products before theirs status will be set
+     *
+     * @param array $productIds
+     * @param int $status
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function _validateMassStatus(array $productIds, $status)
+    {
+        if ($status == \Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED) {
+            if (!$this->_objectManager->create('Magento\Catalog\Model\Product')->isProductsHasSku($productIds)) {
+                throw new \Magento\Framework\Model\Exception(
+                    __('Please make sure to define SKU values for all processed products.')
+                );
+            }
+        }
+    }
+
+    /**
+     * Update product(s) status action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $productIds = (array) $this->getRequest()->getParam('product');
+        $storeId = (int) $this->getRequest()->getParam('store', 0);
+        $status = (int) $this->getRequest()->getParam('status');
+
+        try {
+            $this->_validateMassStatus($productIds, $status);
+            $this->_objectManager->get('Magento\Catalog\Model\Product\Action')
+                ->updateAttributes($productIds, array('status' => $status), $storeId);
+            $this->messageManager->addSuccess(__('A total of %1 record(s) have been updated.', count($productIds)));
+            $this->_productPriceIndexerProcessor->reindexList($productIds);
+        } catch (\Magento\Core\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_getSession()->addException($e, __('Something went wrong while updating the product(s) status.'));
+        }
+
+        $this->_redirect('catalog/*/', array('store' => $storeId));
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..45e924542f6f6ec16b811559b880c6b4e6784fc8
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/NewAction.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var Initialization\StockDataFilter
+     */
+    protected $stockFilter;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param Initialization\StockDataFilter $stockFilter
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        Initialization\StockDataFilter $stockFilter
+    ) {
+        $this->stockFilter;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * Create new product page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->getRequest()->getParam('set')) {
+            $this->_forward('noroute');
+            return;
+        }
+        $this->_title->add(__('Products'));
+
+        $product = $this->productBuilder->build($this->getRequest());
+
+        $productData = $this->getRequest()->getPost('product');
+        if ($productData) {
+            $stockData = isset($productData['stock_data']) ? $productData['stock_data'] : array();
+            $productData['stock_data'] = $this->stockFilter->filter($stockData);
+            $product->addData($productData);
+        }
+
+        $this->_title->add(__('New Product'));
+
+        $this->_eventManager->dispatch('catalog_product_new_action', array('product' => $product));
+
+        if ($this->getRequest()->getParam('popup')) {
+            $this->_view->loadLayout(array(
+                'popup',
+                strtolower($this->_request->getFullActionName()),
+                'catalog_product_' . $product->getTypeId()
+            ));
+        } else {
+            $this->_view->loadLayout(
+                array(
+                    'default',
+                    strtolower($this->_request->getFullActionName()),
+                    'catalog_product_' . $product->getTypeId()
+                )
+            );
+            $this->_setActiveMenu('Magento_Catalog::catalog_products');
+        }
+
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $block = $this->_view->getLayout()->getBlock('catalog.wysiwyg.js');
+        if ($block) {
+            $block->setStoreId($product->getStoreId());
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Options.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Options.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb4b4a875729e7b57d2987dd65411b0e73f991b3
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Options.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Options extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get options fieldset block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/OptionsImportGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/OptionsImportGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c4327e6969751511a4eeae6b3a2c19ae188adba
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/OptionsImportGrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class OptionsImportGrid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Show product grid for custom options import popup
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Related.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Related.php
new file mode 100644
index 0000000000000000000000000000000000000000..423a0b66946c1302f1b957e3c5691bd4d8af8a60
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Related.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Get related products grid and serializer block
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Related extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.related')
+            ->setProductsRelated($this->getRequest()->getPost('products_related', null));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/RelatedGrid.php
similarity index 87%
rename from app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds.php
rename to app/code/Magento/Catalog/Controller/Adminhtml/Product/RelatedGrid.php
index 95f302783133d41abf7e53ed8fb0b4c3873aa237..cf184bf07e1937eedd911885c065ca69a4c4aff7 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Datafeeds.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/RelatedGrid.php
@@ -1,5 +1,7 @@
 <?php
 /**
+ * Get related products grid
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,12 +25,6 @@
  */
 namespace Magento\Catalog\Controller\Adminhtml\Product;
 
-class Datafeeds extends \Magento\Backend\App\Action
+class RelatedGrid extends Related
 {
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e7da52f40eb8ae8b3411834f006859400dc3761
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Save.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var Initialization\Helper
+     */
+    protected $initializationHelper;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Copier
+     */
+    protected $productCopier;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\TypeTransitionManager
+     */
+    protected $productTypeManager;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param Initialization\Helper $initializationHelper
+     * @param \Magento\Catalog\Model\Product\Copier $productCopier
+     * @param \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        Initialization\Helper $initializationHelper,
+        \Magento\Catalog\Model\Product\Copier $productCopier,
+        \Magento\Catalog\Model\Product\TypeTransitionManager $productTypeManager
+    ) {
+        $this->initializationHelper = $initializationHelper;
+        $this->productCopier = $productCopier;
+        $this->productTypeManager = $productTypeManager;
+        parent::__construct($context, $productBuilder);
+    }
+
+
+    /**
+     * Save product action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $storeId = $this->getRequest()->getParam('store');
+        $redirectBack = $this->getRequest()->getParam('back', false);
+        $productId = $this->getRequest()->getParam('id');
+
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $product = $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
+            $this->productTypeManager->processProduct($product);
+
+            try {
+                if (isset($data['product'][$product->getIdFieldName()])) {
+                    throw new \Magento\Framework\Model\Exception(__('Unable to save product'));
+                }
+
+                $originalSku = $product->getSku();
+                $product->save();
+                $productId = $product->getId();
+
+                /**
+                 * Do copying data to stores
+                 */
+                if (isset($data['copy_to_stores'])) {
+                    foreach ($data['copy_to_stores'] as $storeTo => $storeFrom) {
+                        $this->_objectManager->create('Magento\Catalog\Model\Product')
+                            ->setStoreId($storeFrom)
+                            ->load($productId)
+                            ->setStoreId($storeTo)
+                            ->save();
+                    }
+                }
+
+                $this->_objectManager->create('Magento\CatalogRule\Model\Rule')->applyAllRulesToProduct($productId);
+
+                $this->messageManager->addSuccess(__('You saved the product.'));
+                if ($product->getSku() != $originalSku) {
+                    $this->messageManager->addNotice(
+                        __(
+                            'SKU for product %1 has been changed to %2.',
+                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName()),
+                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getSku())
+                        )
+                    );
+                }
+
+                $this->_eventManager->dispatch(
+                    'controller_action_catalog_product_save_entity_after',
+                    array('controller' => $this)
+                );
+
+                if ($redirectBack === 'duplicate') {
+                    $newProduct = $this->productCopier->copy($product);
+                    $this->messageManager->addSuccess(__('You duplicated the product.'));
+                }
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_session->setProductData($data);
+                $redirectBack = true;
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError($e->getMessage());
+                $redirectBack = true;
+            }
+        }
+
+        if ($redirectBack === 'new') {
+            $this->_redirect(
+                'catalog/*/new',
+                array('set' => $product->getAttributeSetId(), 'type' => $product->getTypeId())
+            );
+        } elseif ($redirectBack === 'duplicate' && isset($newProduct)) {
+            $this->_redirect(
+                'catalog/*/edit',
+                array('id' => $newProduct->getId(), 'back' => null, '_current' => true)
+            );
+        } elseif ($redirectBack) {
+            $this->_redirect('catalog/*/edit', array('id' => $productId, '_current' => true));
+        } else {
+            $this->_redirect('catalog/*/', array('store' => $storeId));
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php
index 36ba0bd9f6a5d06897dcbc784ebcfe6028972605..a36cdbdc6c17198648324a191233aeb2bdae38cb 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set.php
@@ -47,202 +47,6 @@ class Set extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Product Templates'));
-
-        $this->_setTypeId();
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
-
-        $this->_addBreadcrumb(__('Catalog'), __('Catalog'));
-        $this->_addBreadcrumb(__('Manage Attribute Sets'), __('Manage Attribute Sets'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Product Templates'));
-
-        $this->_setTypeId();
-        $attributeSet = $this->_objectManager->create(
-            'Magento\Eav\Model\Entity\Attribute\Set'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!$attributeSet->getId()) {
-            $this->_redirect('catalog/*/index');
-            return;
-        }
-
-        $this->_title->add($attributeSet->getId() ? $attributeSet->getAttributeSetName() : __('New Set'));
-
-        $this->_coreRegistry->register('current_attribute_set', $attributeSet);
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
-        $this->_addBreadcrumb(__('Catalog'), __('Catalog'));
-        $this->_addBreadcrumb(__('Manage Product Sets'), __('Manage Product Sets'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function setGridAction()
-    {
-        $this->_setTypeId();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save attribute set action
-     *
-     * [POST] Create attribute set from another set and redirect to edit page
-     * [AJAX] Save attribute set data
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $entityTypeId = $this->_getEntityTypeId();
-        $hasError = false;
-        $attributeSetId = $this->getRequest()->getParam('id', false);
-        $isNewSet = $this->getRequest()->getParam('gotoEdit', false) == '1';
-
-        /* @var $model \Magento\Eav\Model\Entity\Attribute\Set */
-        $model = $this->_objectManager->create(
-            'Magento\Eav\Model\Entity\Attribute\Set'
-        )->setEntityTypeId(
-            $entityTypeId
-        );
-
-        /** @var $filterManager \Magento\Framework\Filter\FilterManager */
-        $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
-
-        try {
-            if ($isNewSet) {
-                //filter html tags
-                $name = $filterManager->stripTags($this->getRequest()->getParam('attribute_set_name'));
-                $model->setAttributeSetName(trim($name));
-            } else {
-                if ($attributeSetId) {
-                    $model->load($attributeSetId);
-                }
-                if (!$model->getId()) {
-                    throw new \Magento\Framework\Model\Exception(__('This attribute set no longer exists.'));
-                }
-                $data = $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->jsonDecode(
-                    $this->getRequest()->getPost('data')
-                );
-
-                //filter html tags
-                $data['attribute_set_name'] = $filterManager->stripTags($data['attribute_set_name']);
-
-                $model->organizeData($data);
-            }
-
-            $model->validate();
-            if ($isNewSet) {
-                $model->save();
-                $model->initFromSkeleton($this->getRequest()->getParam('skeleton_set'));
-            }
-            $model->save();
-            $this->messageManager->addSuccess(__('You saved the attribute set.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $hasError = true;
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while saving the attribute set.'));
-            $hasError = true;
-        }
-
-        if ($isNewSet) {
-            if ($this->getRequest()->getPost('return_session_messages_only')) {
-                /** @var $block \Magento\Framework\View\Element\Messages */
-                $block = $this->_objectManager->get('Magento\Framework\View\Element\Messages');
-                $block->setMessages($this->messageManager->getMessages(true));
-                $body = $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->jsonEncode(
-                    array('messages' => $block->getGroupedHtml(), 'error' => $hasError, 'id' => $model->getId())
-                );
-                $this->getResponse()->representJson($body);
-            } else {
-                if ($hasError) {
-                    $this->_redirect('catalog/*/add');
-                } else {
-                    $this->_redirect('catalog/*/edit', array('id' => $model->getId()));
-                }
-            }
-        } else {
-            $response = array();
-            if ($hasError) {
-                $this->_view->getLayout()->initMessages();
-                $response['error'] = 1;
-                $response['message'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml();
-            } else {
-                $response['error'] = 0;
-                $response['url'] = $this->getUrl('catalog/*/');
-            }
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function addAction()
-    {
-        $this->_title->add(__('New Product Template'));
-
-        $this->_setTypeId();
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
-
-
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Product\Attribute\Set\Toolbar\Add')
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $setId = $this->getRequest()->getParam('id');
-        try {
-            $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')->setId($setId)->delete();
-
-            $this->messageManager->addSuccess(__('The attribute set has been removed.'));
-            $this->getResponse()->setRedirect($this->getUrl('catalog/*/'));
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while deleting this set.'));
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-        }
-    }
-
     /**
      * Define in register catalog_product entity type code as entityType
      *
@@ -263,17 +67,4 @@ class Set extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Catalog::sets');
     }
-
-    /**
-     * Retrieve catalog product entity type id
-     *
-     * @return int
-     */
-    protected function _getEntityTypeId()
-    {
-        if (is_null($this->_coreRegistry->registry('entityType'))) {
-            $this->_setTypeId();
-        }
-        return $this->_coreRegistry->registry('entityType');
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Add.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f2577a9d6271d0628d219b8a15e43a83285393f
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Add.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class Add extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('New Product Template'));
+
+        $this->_setTypeId();
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
+
+
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Adminhtml\Product\Attribute\Set\Toolbar\Add')
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Delete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..db8557897d8313f6405ac7f40584368e77634721
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Delete.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class Delete extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $setId = $this->getRequest()->getParam('id');
+        try {
+            $this->_objectManager->create('Magento\Eav\Model\Entity\Attribute\Set')->setId($setId)->delete();
+
+            $this->messageManager->addSuccess(__('The attribute set has been removed.'));
+            $this->getResponse()->setRedirect($this->getUrl('catalog/*/'));
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while deleting this set.'));
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dac12620e5f837755346e6f14d943bee1f97a7d
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Edit.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Product Templates'));
+
+        $this->_setTypeId();
+        $attributeSet = $this->_objectManager->create(
+            'Magento\Eav\Model\Entity\Attribute\Set'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!$attributeSet->getId()) {
+            $this->_redirect('catalog/*/index');
+            return;
+        }
+
+        $this->_title->add($attributeSet->getId() ? $attributeSet->getAttributeSetName() : __('New Set'));
+
+        $this->_coreRegistry->register('current_attribute_set', $attributeSet);
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $this->_addBreadcrumb(__('Catalog'), __('Catalog'));
+        $this->_addBreadcrumb(__('Manage Product Sets'), __('Manage Product Sets'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e8567fec766cf02590e276a0a90c1a768f0c796
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Index.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Product Templates'));
+
+        $this->_setTypeId();
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Catalog::catalog_attributes_sets');
+
+        $this->_addBreadcrumb(__('Catalog'), __('Catalog'));
+        $this->_addBreadcrumb(__('Manage Attribute Sets'), __('Manage Attribute Sets'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..58e9f6ab438c2c9327e2d3c53f094254e4bc126f
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/Save.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * Retrieve catalog product entity type id
+     *
+     * @return int
+     */
+    protected function _getEntityTypeId()
+    {
+        if (is_null($this->_coreRegistry->registry('entityType'))) {
+            $this->_setTypeId();
+        }
+        return $this->_coreRegistry->registry('entityType');
+    }
+
+    /**
+     * Save attribute set action
+     *
+     * [POST] Create attribute set from another set and redirect to edit page
+     * [AJAX] Save attribute set data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $entityTypeId = $this->_getEntityTypeId();
+        $hasError = false;
+        $attributeSetId = $this->getRequest()->getParam('id', false);
+        $isNewSet = $this->getRequest()->getParam('gotoEdit', false) == '1';
+
+        /* @var $model \Magento\Eav\Model\Entity\Attribute\Set */
+        $model = $this->_objectManager->create(
+            'Magento\Eav\Model\Entity\Attribute\Set'
+        )->setEntityTypeId(
+            $entityTypeId
+        );
+
+        /** @var $filterManager \Magento\Framework\Filter\FilterManager */
+        $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
+
+        try {
+            if ($isNewSet) {
+                //filter html tags
+                $name = $filterManager->stripTags($this->getRequest()->getParam('attribute_set_name'));
+                $model->setAttributeSetName(trim($name));
+            } else {
+                if ($attributeSetId) {
+                    $model->load($attributeSetId);
+                }
+                if (!$model->getId()) {
+                    throw new \Magento\Framework\Model\Exception(__('This attribute set no longer exists.'));
+                }
+                $data = $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->jsonDecode(
+                    $this->getRequest()->getPost('data')
+                );
+
+                //filter html tags
+                $data['attribute_set_name'] = $filterManager->stripTags($data['attribute_set_name']);
+
+                $model->organizeData($data);
+            }
+
+            $model->validate();
+            if ($isNewSet) {
+                $model->save();
+                $model->initFromSkeleton($this->getRequest()->getParam('skeleton_set'));
+            }
+            $model->save();
+            $this->messageManager->addSuccess(__('You saved the attribute set.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $hasError = true;
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while saving the attribute set.'));
+            $hasError = true;
+        }
+
+        if ($isNewSet) {
+            if ($this->getRequest()->getPost('return_session_messages_only')) {
+                /** @var $block \Magento\Framework\View\Element\Messages */
+                $block = $this->_objectManager->get('Magento\Framework\View\Element\Messages');
+                $block->setMessages($this->messageManager->getMessages(true));
+                $body = $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->jsonEncode(
+                    array('messages' => $block->getGroupedHtml(), 'error' => $hasError, 'id' => $model->getId())
+                );
+                $this->getResponse()->representJson($body);
+            } else {
+                if ($hasError) {
+                    $this->_redirect('catalog/*/add');
+                } else {
+                    $this->_redirect('catalog/*/edit', array('id' => $model->getId()));
+                }
+            }
+        } else {
+            $response = array();
+            if ($hasError) {
+                $this->_view->getLayout()->initMessages();
+                $response['error'] = 1;
+                $response['message'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml();
+            } else {
+                $response['error'] = 0;
+                $response['url'] = $this->getUrl('catalog/*/');
+            }
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/SetGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/SetGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5dbe1569d946638f3e14d376b2899b5b81b2f00
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Set/SetGrid.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product\Set;
+
+class SetGrid extends \Magento\Catalog\Controller\Adminhtml\Product\Set
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_setTypeId();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/ShowUpdateResult.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..c90f05e93e563a6fcf5f29ed511a6594dd2102b3
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/ShowUpdateResult.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class ShowUpdateResult extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Show item update result from updateAction
+     * in Wishlist and Cart controllers.
+     *
+     * @return bool
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+        if ($session->hasCompositeProductResult()
+            && $session->getCompositeProductResult() instanceof \Magento\Framework\Object
+        ) {
+            $this->_objectManager->get('Magento\Catalog\Helper\Product\Composite')
+                ->renderUpdateResult($session->getCompositeProductResult());
+            $session->unsCompositeProductResult();
+        } else {
+            $session->unsCompositeProductResult();
+            return false;
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestAttributes.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestAttributes.php
new file mode 100644
index 0000000000000000000000000000000000000000..ebcc99af3d526183c22dc77bad052861192f3654
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestAttributes.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class SuggestAttributes extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Search for attributes by part of attribute's label in admin store
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Attributes\Search'
+                )->getSuggestedAttributes(
+                    $this->getRequest()->getParam('label_part')
+                )
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestProductTemplates.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestProductTemplates.php
new file mode 100644
index 0000000000000000000000000000000000000000..48489b98fcd3547ba51b2150e8d102bf077e847c
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/SuggestProductTemplates.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class SuggestProductTemplates extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Action for product template selector
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
+                $this->_view->getLayout()->createBlock('Magento\Catalog\Block\Product\TemplateSelector')
+                    ->getSuggestedTemplates($this->getRequest()->getParam('label_part'))
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Upsell.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Upsell.php
new file mode 100644
index 0000000000000000000000000000000000000000..884f386fe1040dfcc287f8d85920a94c6655a068
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Upsell.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Upsell extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get upsell products grid and serializer block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.upsell')
+            ->setProductsUpsell($this->getRequest()->getPost('products_upsell', null));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/UpsellGrid.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/UpsellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d169fa91ed384ac748d4095efe598e8d5851e00
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/UpsellGrid.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class UpsellGrid extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * Get upsell products grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->productBuilder->build($this->getRequest());
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('catalog.product.edit.tab.upsell')
+            ->setProductsRelated($this->getRequest()->getPost('products_upsell', null));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Validate.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..8345786785142f8b3612c0f803dcdd9332db8d24
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Validate.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+use Magento\Backend\App\Action;
+use Magento\Catalog\Controller\Adminhtml\Product;
+
+class Validate extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\Filter\Date
+     */
+    protected $_dateFilter;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Validator
+     */
+    protected $productValidator;
+
+    /**
+     * @param Action\Context $context
+     * @param Builder $productBuilder
+     * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
+     * @param \Magento\Catalog\Model\Product\Validator $productValidator
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        Product\Builder $productBuilder,
+        \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
+        \Magento\Catalog\Model\Product\Validator $productValidator
+    ) {
+        $this->_dateFilter = $dateFilter;
+        $this->productValidator = $productValidator;
+        parent::__construct($context, $productBuilder);
+    }
+
+    /**
+     * Validate product
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(false);
+
+        try {
+            $productData = $this->getRequest()->getPost('product');
+
+            if ($productData && !isset($productData['stock_data']['use_config_manage_stock'])) {
+                $productData['stock_data']['use_config_manage_stock'] = 0;
+            }
+            /* @var $product \Magento\Catalog\Model\Product */
+            $product = $this->_objectManager->create('Magento\Catalog\Model\Product');
+            $product->setData('_edit_mode', true);
+            $storeId = $this->getRequest()->getParam('store');
+            if ($storeId) {
+                $product->setStoreId($storeId);
+            }
+            $setId = $this->getRequest()->getParam('set');
+            if ($setId) {
+                $product->setAttributeSetId($setId);
+            }
+            $typeId = $this->getRequest()->getParam('type');
+            if ($typeId) {
+                $product->setTypeId($typeId);
+            }
+            $productId = $this->getRequest()->getParam('id');
+            if ($productId) {
+                $product->load($productId);
+            }
+
+            $dateFieldFilters = array();
+            $attributes = $product->getAttributes();
+            foreach ($attributes as $attrKey => $attribute) {
+                if ($attribute->getBackend()->getType() == 'datetime') {
+                    if (array_key_exists($attrKey, $productData) && $productData[$attrKey] != '') {
+                        $dateFieldFilters[$attrKey] = $this->_dateFilter;
+                    }
+                }
+            }
+            $inputFilter = new \Zend_Filter_Input($dateFieldFilters, array(), $productData);
+            $productData = $inputFilter->getUnescaped();
+            $product->addData($productData);
+
+            /* set restrictions for date ranges */
+            $resource = $product->getResource();
+            $resource->getAttribute('special_from_date')->setMaxValue($product->getSpecialToDate());
+            $resource->getAttribute('news_from_date')->setMaxValue($product->getNewsToDate());
+            $resource->getAttribute('custom_design_from')->setMaxValue($product->getCustomDesignTo());
+
+            $this->productValidator->validate($product, $this->getRequest(), $response);
+        } catch (\Magento\Eav\Model\Entity\Attribute\Exception $e) {
+            $response->setError(true);
+            $response->setAttribute($e->getAttributeCode());
+            $response->setMessage($e->getMessage());
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response->setError(true);
+            $response->setMessage($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_view->getLayout()->initMessages();
+            $response->setError(true);
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget/Chooser.php
similarity index 90%
rename from app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget.php
rename to app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget/Chooser.php
index 20d9c1bc1fe14abcf86327732a4fd5afa4500ff8..967cc931b473bd1c5588893eac4f721317e97d30 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Widget/Chooser.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller\Adminhtml\Product;
+namespace Magento\Catalog\Controller\Adminhtml\Product\Widget;
 
-/**
- * Catalog Product widgets controller for CMS WYSIWYG
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Widget extends \Magento\Backend\App\Action
+class Chooser extends \Magento\Backend\App\Action
 {
     /**
      * Chooser Source action
      *
      * @return void
      */
-    public function chooserAction()
+    public function execute()
     {
         $uniqId = $this->getRequest()->getParam('uniq_id');
         $massAction = $this->getRequest()->getParam('use_massaction', false);
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Product/Wysiwyg.php b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Wysiwyg.php
new file mode 100644
index 0000000000000000000000000000000000000000..82bbbe2b645b4b13df0bb5fbcb3d359b12222101
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Product/Wysiwyg.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class Wysiwyg extends \Magento\Catalog\Controller\Adminhtml\Product
+{
+    /**
+     * WYSIWYG editor action for ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $elementId = $this->getRequest()->getParam('element_id', md5(microtime()));
+        $storeId = $this->getRequest()->getParam('store_id', 0);
+        $storeMediaUrl = $this->_objectManager->get(
+            'Magento\Store\Model\StoreManagerInterface'
+        )->getStore(
+            $storeId
+        )->getBaseUrl(
+            \Magento\Framework\UrlInterface::URL_TYPE_MEDIA
+        );
+
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Catalog\Block\Adminhtml\Helper\Form\Wysiwyg\Content',
+            '',
+            array(
+                'data' => array(
+                    'editor_element_id' => $elementId,
+                    'store_id' => $storeId,
+                    'store_media_url' => $storeMediaUrl
+                )
+            )
+        );
+
+        $this->getResponse()->setBody($content->toHtml());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search.php
index 2ff6e8f9fb1f3fd374f2375a831dff690e858dc7..446e3e8be879b2ea377601198643cff002fbd941 100644
--- a/app/code/Magento/Catalog/Controller/Adminhtml/Search.php
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search.php
@@ -27,23 +27,6 @@ use Magento\Backend\App\Action;
 
 class Search extends \Magento\Backend\App\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
     /**
      * @return $this
      */
@@ -54,169 +37,6 @@ class Search extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Search Terms'));
-
-        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Search Terms'));
-
-        $id = $this->getRequest()->getParam('id');
-        $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
-
-        if ($id) {
-            $model->load($id);
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This search no longer exists.'));
-                $this->_redirect('catalog/*');
-                return;
-            }
-        }
-
-        // set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
-        if (!empty($data)) {
-            $model->addData($data);
-        }
-
-        $this->_coreRegistry->register('current_catalog_search', $model);
-
-        $this->_initAction();
-
-        $this->_title->add($id ? $model->getQueryText() : __('New Search'));
-
-        $this->_view->getLayout()->getBlock('head')->setCanLoadRulesJs(true);
-
-        $this->_view->getLayout()->getBlock(
-            'adminhtml.catalog.search.edit'
-        )->setData(
-            'action',
-            $this->getUrl('catalog/search/save')
-        );
-
-        $this->_addBreadcrumb($id ? __('Edit Search') : __('New Search'), $id ? __('Edit Search') : __('New Search'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save search query
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $hasError = false;
-        $data = $this->getRequest()->getPost();
-        $queryId = $this->getRequest()->getPost('query_id', null);
-        if ($this->getRequest()->isPost() && $data) {
-            /* @var $model \Magento\CatalogSearch\Model\Query */
-            $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
-
-            // validate query
-            $queryText = $this->getRequest()->getPost('query_text', false);
-            $storeId = $this->getRequest()->getPost('store_id', false);
-
-            try {
-                if ($queryText) {
-                    $model->setStoreId($storeId);
-                    $model->loadByQueryText($queryText);
-                    if ($model->getId() && $model->getId() != $queryId) {
-                        throw new \Magento\Framework\Model\Exception(
-                            __('You already have an identical search term query.')
-                        );
-                    } elseif (!$model->getId() && $queryId) {
-                        $model->load($queryId);
-                    }
-                } else if ($queryId) {
-                    $model->load($queryId);
-                }
-
-                $model->addData($data);
-                $model->setIsProcessed(0);
-                $model->save();
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $hasError = true;
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong while saving the search query.'));
-                $hasError = true;
-            }
-        }
-
-        if ($hasError) {
-            $this->_getSession()->setPageData($data);
-            $this->_redirect('catalog/*/edit', array('id' => $queryId));
-        } else {
-            $this->_redirect('catalog/*');
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            try {
-                $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
-                $model->setId($id);
-                $model->delete();
-                $this->messageManager->addSuccess(__('You deleted the search.'));
-                $this->_redirect('catalog/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('catalog/*/edit', array('id' => $this->getRequest()->getParam('id')));
-                return;
-            }
-        }
-        $this->messageManager->addError(__('We can\'t find a search term to delete.'));
-        $this->_redirect('catalog/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $searchIds = $this->getRequest()->getParam('search');
-        if (!is_array($searchIds)) {
-            $this->messageManager->addError(__('Please select catalog searches.'));
-        } else {
-            try {
-                foreach ($searchIds as $searchId) {
-                    $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query')->load($searchId);
-                    $model->delete();
-                }
-                $this->messageManager->addSuccess(__('Total of %1 record(s) were deleted', count($searchIds)));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-        $this->_redirect('catalog/*/index');
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Delete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..e429066aa5f1d6b7547d7e2208808a254a161fac
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Delete.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class Delete extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            try {
+                $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
+                $model->setId($id);
+                $model->delete();
+                $this->messageManager->addSuccess(__('You deleted the search.'));
+                $this->_redirect('catalog/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('catalog/*/edit', array('id' => $this->getRequest()->getParam('id')));
+                return;
+            }
+        }
+        $this->messageManager->addError(__('We can\'t find a search term to delete.'));
+        $this->_redirect('catalog/*/');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..418720fa8d79e519df876715c18f55d5373cfea8
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Edit.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Search Terms'));
+
+        $id = $this->getRequest()->getParam('id');
+        $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
+
+        if ($id) {
+            $model->load($id);
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This search no longer exists.'));
+                $this->_redirect('catalog/*');
+                return;
+            }
+        }
+
+        // set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
+        if (!empty($data)) {
+            $model->addData($data);
+        }
+
+        $this->_coreRegistry->register('current_catalog_search', $model);
+
+        $this->_initAction();
+
+        $this->_title->add($id ? $model->getQueryText() : __('New Search'));
+
+        $this->_view->getLayout()->getBlock('head')->setCanLoadRulesJs(true);
+
+        $this->_view->getLayout()->getBlock(
+            'adminhtml.catalog.search.edit'
+        )->setData(
+            'action',
+            $this->getUrl('catalog/search/save')
+        );
+
+        $this->_addBreadcrumb($id ? __('Edit Search') : __('New Search'), $id ? __('Edit Search') : __('New Search'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Index.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..db4289cb4965b99e4b89ba1e9baed49b64416f11
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Search Terms'));
+
+        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/MassDelete.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..77bef167bfc1fe95806a2905888a7ac18ed56317
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/MassDelete.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $searchIds = $this->getRequest()->getParam('search');
+        if (!is_array($searchIds)) {
+            $this->messageManager->addError(__('Please select catalog searches.'));
+        } else {
+            try {
+                foreach ($searchIds as $searchId) {
+                    $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query')->load($searchId);
+                    $model->delete();
+                }
+                $this->messageManager->addSuccess(__('Total of %1 record(s) were deleted', count($searchIds)));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+        $this->_redirect('catalog/*/index');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/NewAction.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ebbf03fb8e9b35db3716f3d5c55576ff7ea4308
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class NewAction extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Adminhtml/Search/Save.php b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..643d16607141b02b8affbf44c5a487eddc406ae9
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Adminhtml/Search/Save.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Search;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Search
+{
+    /**
+     * Save search query
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $hasError = false;
+        $data = $this->getRequest()->getPost();
+        $queryId = $this->getRequest()->getPost('query_id', null);
+        if ($this->getRequest()->isPost() && $data) {
+            /* @var $model \Magento\CatalogSearch\Model\Query */
+            $model = $this->_objectManager->create('Magento\CatalogSearch\Model\Query');
+
+            // validate query
+            $queryText = $this->getRequest()->getPost('query_text', false);
+            $storeId = $this->getRequest()->getPost('store_id', false);
+
+            try {
+                if ($queryText) {
+                    $model->setStoreId($storeId);
+                    $model->loadByQueryText($queryText);
+                    if ($model->getId() && $model->getId() != $queryId) {
+                        throw new \Magento\Framework\Model\Exception(
+                            __('You already have an identical search term query.')
+                        );
+                    } elseif (!$model->getId() && $queryId) {
+                        $model->load($queryId);
+                    }
+                } else if ($queryId) {
+                    $model->load($queryId);
+                }
+
+                $model->addData($data);
+                $model->setIsProcessed(0);
+                $model->save();
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $hasError = true;
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong while saving the search query.'));
+                $hasError = true;
+            }
+        }
+
+        if ($hasError) {
+            $this->_getSession()->setPageData($data);
+            $this->_redirect('catalog/*/edit', array('id' => $queryId));
+        } else {
+            $this->_redirect('catalog/*');
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Category.php b/app/code/Magento/Catalog/Controller/Category/View.php
similarity index 96%
rename from app/code/Magento/Catalog/Controller/Category.php
rename to app/code/Magento/Catalog/Controller/Category/View.php
index 96d2bd774cde706f7b4584c36621b4850cedaef1..6a2fda5a8b17e7d0eb1d5fd22c8c2ef1bff735a5 100644
--- a/app/code/Magento/Catalog/Controller/Category.php
+++ b/app/code/Magento/Catalog/Controller/Category/View.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller;
+namespace Magento\Catalog\Controller\Category;
 
-/**
- * Category controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Category extends \Magento\Framework\App\Action\Action
+class View extends \Magento\Framework\App\Action\Action
 {
     /**
      * Core registry
@@ -129,7 +125,7 @@ class Category extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function viewAction()
+    public function execute()
     {
         if ($this->_request->getParam(\Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED)) {
             $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
diff --git a/app/code/Magento/Catalog/Controller/Index.php b/app/code/Magento/Catalog/Controller/Index/Index.php
similarity index 93%
rename from app/code/Magento/Catalog/Controller/Index.php
rename to app/code/Magento/Catalog/Controller/Index/Index.php
index 4eb13fd34b78688902ccf65879271995372984f0..0d79d137a5b1ed44f0702b926fe32e73a2243d9d 100644
--- a/app/code/Magento/Catalog/Controller/Index.php
+++ b/app/code/Magento/Catalog/Controller/Index/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,7 +22,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller;
+namespace Magento\Catalog\Controller\Index;
 
 class Index extends \Magento\Framework\App\Action\Action
 {
@@ -30,7 +31,7 @@ class Index extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->_redirect('/');
     }
diff --git a/app/code/Magento/Catalog/Controller/Product.php b/app/code/Magento/Catalog/Controller/Product.php
index 09675cb950da693afc0dd838bceca83f28544660..1c583863ab9cb005bd7629f9a935bdd5facaef3e 100644
--- a/app/code/Magento/Catalog/Controller/Product.php
+++ b/app/code/Magento/Catalog/Controller/Product.php
@@ -44,101 +44,4 @@ class Product extends \Magento\Framework\App\Action\Action implements \Magento\C
 
         return $this->_objectManager->get('Magento\Catalog\Helper\Product')->initProduct($productId, $this, $params);
     }
-
-    /**
-     * Initialize product view layout
-     *
-     * @param ModelProduct $product
-     * @return $this
-     */
-    protected function _initProductLayout($product)
-    {
-        $this->_objectManager->get('Magento\Catalog\Helper\Product\View')->initProductLayout($product, $this);
-        return $this;
-    }
-
-    /**
-     * Product view action
-     *
-     * @return void
-     */
-
-    /**
-     * Product view action
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        // Get initial data from request
-        $categoryId = (int) $this->getRequest()->getParam('category', false);
-        $productId = (int) $this->getRequest()->getParam('id');
-        $specifyOptions = $this->getRequest()->getParam('options');
-
-        if ($this->getRequest()->isPost() && $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
-            $product = $this->_initProduct();
-            if (!$product) {
-                $this->noProductRedirect();
-            }
-            if ($specifyOptions) {
-                $notice = $product->getTypeInstance()->getSpecifyOptionMessage();
-                $this->messageManager->addNotice($notice);
-            }
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-            return;
-        }
-
-        // Prepare helper and params
-        /** @var \Magento\Catalog\Helper\Product\View $viewHelper */
-        $viewHelper = $this->_objectManager->get('Magento\Catalog\Helper\Product\View');
-
-        $params = new \Magento\Framework\Object();
-        $params->setCategoryId($categoryId);
-        $params->setSpecifyOptions($specifyOptions);
-
-        // Render page
-        try {
-            $viewHelper->prepareAndRender($productId, $this, $params);
-        } catch (\Exception $e) {
-            if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) {
-                $this->noProductRedirect();
-            } else {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->_forward('noroute');
-            }
-        }
-    }
-
-    /**
-     * View product gallery action
-     *
-     * @return void
-     */
-    public function galleryAction()
-    {
-        if (!$this->_initProduct()) {
-            if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) {
-                $this->_redirect('');
-            } elseif (!$this->getResponse()->isRedirect()) {
-                $this->_forward('noroute');
-            }
-            return;
-        }
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Redirect if product failed to load
-     *
-     * @return void
-     */
-    protected function noProductRedirect()
-    {
-        if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) {
-            $this->_redirect('');
-        } elseif (!$this->getResponse()->isRedirect()) {
-            $this->_forward('noroute');
-        }
-    }
 }
diff --git a/app/code/Magento/Catalog/Controller/Product/Compare.php b/app/code/Magento/Catalog/Controller/Product/Compare.php
index 89710cd1b757fe74e9a8f3785c11915a4f020986..24c7f8be1f138e5b371e77ed811ecf7e338c2e94 100644
--- a/app/code/Magento/Catalog/Controller/Product/Compare.php
+++ b/app/code/Magento/Catalog/Controller/Product/Compare.php
@@ -134,143 +134,6 @@ class Compare extends \Magento\Framework\App\Action\Action
         parent::__construct($context);
     }
 
-    /**
-     * Compare index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $items = $this->getRequest()->getParam('items');
-
-        $beforeUrl = $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED);
-        if ($beforeUrl) {
-            $this->_catalogSession->setBeforeCompareUrl(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->urlDecode($beforeUrl)
-            );
-        }
-
-        if ($items) {
-            $items = explode(',', $items);
-            /** @var \Magento\Catalog\Model\Product\Compare\ListCompare $list */
-            $list = $this->_catalogProductCompareList;
-            $list->addProducts($items);
-            $this->_redirect('*/*/*');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Add item to compare list
-     *
-     * @return void
-     */
-    public function addAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            return;
-        }
-
-        $productId = (int)$this->getRequest()->getParam('product');
-        if ($productId && ($this->_logVisitor->getId() || $this->_customerSession->isLoggedIn())) {
-            /** @var \Magento\Catalog\Model\Product $product */
-            $product = $this->_productFactory->create();
-            $product->setStoreId($this->_storeManager->getStore()->getId())->load($productId);
-
-            if ($product->getId()) {
-                $this->_catalogProductCompareList->addProduct($product);
-                $productName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName());
-                $this->messageManager->addSuccess(__('You added product %1 to the comparison list.', $productName));
-                $this->_eventManager->dispatch('catalog_product_compare_add_product', array('product' => $product));
-            }
-
-            $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare')->calculate();
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Remove item from compare list
-     *
-     * @return void
-     */
-    public function removeAction()
-    {
-        $productId = (int)$this->getRequest()->getParam('product');
-        if ($productId) {
-            /** @var \Magento\Catalog\Model\Product $product */
-            $product = $this->_productFactory->create();
-            $product->setStoreId($this->_storeManager->getStore()->getId())->load($productId);
-
-            if ($product->getId()) {
-                /** @var $item \Magento\Catalog\Model\Product\Compare\Item */
-                $item = $this->_compareItemFactory->create();
-                if ($this->_customerSession->isLoggedIn()) {
-                    $item->setCustomerId($this->_customerSession->getCustomerId());
-                } elseif ($this->_customerId) {
-                    $item->setCustomerId($this->_customerId);
-                } else {
-                    $item->addVisitorId($this->_logVisitor->getId());
-                }
-
-                $item->loadByProduct($product);
-                /** @var $helper \Magento\Catalog\Helper\Product\Compare */
-                $helper = $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare');
-                if ($item->getId()) {
-                    $item->delete();
-                    $productName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName());
-                    $this->messageManager->addSuccess(
-                        __('You removed product %1 from the comparison list.', $productName)
-                    );
-                    $this->_eventManager->dispatch(
-                        'catalog_product_compare_remove_product',
-                        array('product' => $item)
-                    );
-                    $helper->calculate();
-                }
-            }
-        }
-
-        if (!$this->getRequest()->getParam('isAjax', false)) {
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-        }
-    }
-
-    /**
-     * Remove all items from comparison list
-     *
-     * @return void
-     */
-    public function clearAction()
-    {
-        /** @var \Magento\Catalog\Model\Resource\Product\Compare\Item\Collection $items */
-        $items = $this->_itemCollectionFactory->create();
-
-        if ($this->_customerSession->isLoggedIn()) {
-            $items->setCustomerId($this->_customerSession->getCustomerId());
-        } elseif ($this->_customerId) {
-            $items->setCustomerId($this->_customerId);
-        } else {
-            $items->setVisitorId($this->_logVisitor->getId());
-        }
-
-        try {
-            $items->clear();
-            $this->messageManager->addSuccess(__('You cleared the comparison list.'));
-            $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare')->calculate();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Something went wrong  clearing the comparison list.'));
-        }
-
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
     /**
      * Setter for customer id
      *
diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Add.php b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..6cab38dfae2a28b9d7dc3de180c3316bab965299
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/Compare/Add.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product\Compare;
+
+class Add extends \Magento\Catalog\Controller\Product\Compare
+{
+    /**
+     * Add item to compare list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+            return;
+        }
+
+        $productId = (int)$this->getRequest()->getParam('product');
+        if ($productId && ($this->_logVisitor->getId() || $this->_customerSession->isLoggedIn())) {
+            /** @var \Magento\Catalog\Model\Product $product */
+            $product = $this->_productFactory->create();
+            $product->setStoreId($this->_storeManager->getStore()->getId())->load($productId);
+
+            if ($product->getId()) {
+                $this->_catalogProductCompareList->addProduct($product);
+                $productName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName());
+                $this->messageManager->addSuccess(__('You added product %1 to the comparison list.', $productName));
+                $this->_eventManager->dispatch('catalog_product_compare_add_product', array('product' => $product));
+            }
+
+            $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare')->calculate();
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Clear.php b/app/code/Magento/Catalog/Controller/Product/Compare/Clear.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2c1004257519b861391bd54f6efe0d469253ea9
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/Compare/Clear.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product\Compare;
+
+class Clear extends \Magento\Catalog\Controller\Product\Compare
+{
+    /**
+     * Remove all items from comparison list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Product\Compare\Item\Collection $items */
+        $items = $this->_itemCollectionFactory->create();
+
+        if ($this->_customerSession->isLoggedIn()) {
+            $items->setCustomerId($this->_customerSession->getCustomerId());
+        } elseif ($this->_customerId) {
+            $items->setCustomerId($this->_customerId);
+        } else {
+            $items->setVisitorId($this->_logVisitor->getId());
+        }
+
+        try {
+            $items->clear();
+            $this->messageManager->addSuccess(__('You cleared the comparison list.'));
+            $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare')->calculate();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Something went wrong  clearing the comparison list.'));
+        }
+
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Index.php b/app/code/Magento/Catalog/Controller/Product/Compare/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..61ffc81e66f6268df61bfc4eaf90197c969d6610
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/Compare/Index.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product\Compare;
+
+class Index extends \Magento\Catalog\Controller\Product\Compare
+{
+    /**
+     * Compare index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $items = $this->getRequest()->getParam('items');
+
+        $beforeUrl = $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED);
+        if ($beforeUrl) {
+            $this->_catalogSession->setBeforeCompareUrl(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->urlDecode($beforeUrl)
+            );
+        }
+
+        if ($items) {
+            $items = explode(',', $items);
+            /** @var \Magento\Catalog\Model\Product\Compare\ListCompare $list */
+            $list = $this->_catalogProductCompareList;
+            $list->addProducts($items);
+            $this->_redirect('*/*/*');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php
new file mode 100644
index 0000000000000000000000000000000000000000..7380db349bfa0a276434ca751ffba80101e86276
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/Compare/Remove.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product\Compare;
+
+class Remove extends \Magento\Catalog\Controller\Product\Compare
+{
+    /**
+     * Remove item from compare list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $productId = (int)$this->getRequest()->getParam('product');
+        if ($productId) {
+            /** @var \Magento\Catalog\Model\Product $product */
+            $product = $this->_productFactory->create();
+            $product->setStoreId($this->_storeManager->getStore()->getId())->load($productId);
+
+            if ($product->getId()) {
+                /** @var $item \Magento\Catalog\Model\Product\Compare\Item */
+                $item = $this->_compareItemFactory->create();
+                if ($this->_customerSession->isLoggedIn()) {
+                    $item->setCustomerId($this->_customerSession->getCustomerId());
+                } elseif ($this->_customerId) {
+                    $item->setCustomerId($this->_customerId);
+                } else {
+                    $item->addVisitorId($this->_logVisitor->getId());
+                }
+
+                $item->loadByProduct($product);
+                /** @var $helper \Magento\Catalog\Helper\Product\Compare */
+                $helper = $this->_objectManager->get('Magento\Catalog\Helper\Product\Compare');
+                if ($item->getId()) {
+                    $item->delete();
+                    $productName = $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName());
+                    $this->messageManager->addSuccess(
+                        __('You removed product %1 from the comparison list.', $productName)
+                    );
+                    $this->_eventManager->dispatch(
+                        'catalog_product_compare_remove_product',
+                        array('product' => $item)
+                    );
+                    $helper->calculate();
+                }
+            }
+        }
+
+        if (!$this->getRequest()->getParam('isAjax', false)) {
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Product/Gallery.php b/app/code/Magento/Catalog/Controller/Product/Gallery.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e160cf37464cb8e2c7646fc9b776745ceb81f97
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/Gallery.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product;
+
+class Gallery extends \Magento\Catalog\Controller\Product
+{
+    /**
+     * View product gallery action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_initProduct()) {
+            if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) {
+                $this->_redirect('');
+            } elseif (!$this->getResponse()->isRedirect()) {
+                $this->_forward('noroute');
+            }
+            return;
+        }
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Catalog/Controller/Product/View.php b/app/code/Magento/Catalog/Controller/Product/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5773bd29a2c7660eaab16ef5bf1fcd8fb642b66
--- /dev/null
+++ b/app/code/Magento/Catalog/Controller/Product/View.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Product;
+
+class View extends \Magento\Catalog\Controller\Product
+{
+    /**
+     * Redirect if product failed to load
+     *
+     * @return void
+     */
+    protected function noProductRedirect()
+    {
+        if (isset($_GET['store']) && !$this->getResponse()->isRedirect()) {
+            $this->_redirect('');
+        } elseif (!$this->getResponse()->isRedirect()) {
+            $this->_forward('noroute');
+        }
+    }
+
+    /**
+     * Product view action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // Get initial data from request
+        $categoryId = (int) $this->getRequest()->getParam('category', false);
+        $productId = (int) $this->getRequest()->getParam('id');
+        $specifyOptions = $this->getRequest()->getParam('options');
+
+        if ($this->getRequest()->isPost() && $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
+            $product = $this->_initProduct();
+            if (!$product) {
+                $this->noProductRedirect();
+            }
+            if ($specifyOptions) {
+                $notice = $product->getTypeInstance()->getSpecifyOptionMessage();
+                $this->messageManager->addNotice($notice);
+            }
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+            return;
+        }
+
+        // Prepare helper and params
+        /** @var \Magento\Catalog\Helper\Product\View $viewHelper */
+        $viewHelper = $this->_objectManager->get('Magento\Catalog\Helper\Product\View');
+
+        $params = new \Magento\Framework\Object();
+        $params->setCategoryId($categoryId);
+        $params->setSpecifyOptions($specifyOptions);
+
+        // Render page
+        try {
+            $viewHelper->prepareAndRender($productId, $this, $params);
+        } catch (\Exception $e) {
+            if ($e->getCode() == $viewHelper->ERR_NO_PRODUCT_LOADED) {
+                $this->noProductRedirect();
+            } else {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_forward('noroute');
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Helper/Image.php b/app/code/Magento/Catalog/Helper/Image.php
index c8b88b31b05335e446f331635eab139d29e40d61..51c5a493ffa777c2333a269c48f2b83cd222629c 100644
--- a/app/code/Magento/Catalog/Helper/Image.php
+++ b/app/code/Magento/Catalog/Helper/Image.php
@@ -437,7 +437,7 @@ class Image extends AbstractHelper
             $url = $this->_assetRepo->getUrl($this->getPlaceholder());
         } catch (\Exception $e) {
             $this->_logger->logException($e);
-            $url = $this->_urlBuilder->getUrl('', array('_direct' => 'core/index/notfound'));
+            $url = $this->_urlBuilder->getUrl('', array('_direct' => 'core/index/notFound'));
         }
         return $url;
     }
diff --git a/app/code/Magento/Catalog/Helper/Product/Price.php b/app/code/Magento/Catalog/Helper/Product/Price.php
deleted file mode 100644
index d28712eee130b3df8f3cd5dd197cf30dfb28299b..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Helper/Product/Price.php
+++ /dev/null
@@ -1,147 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Helper\Product;
-
-use Magento\Catalog\Model\Product;
-use Magento\Customer\Service\V1\Data\Customer;
-
-/**
- * Collection of tax module calls
- */
-class Price extends \Magento\Framework\App\Helper\AbstractHelper
-{
-    /**
-     * @var \Magento\Tax\Helper\Data
-     */
-    protected $taxData;
-
-    /**
-     * @var \Magento\Tax\Model\Calculation
-     */
-    protected $taxCalculation;
-
-    /**
-     * @param \Magento\Tax\Helper\Data $taxData
-     * @param \Magento\Tax\Model\Calculation $taxCalculation
-     */
-    public function __construct(\Magento\Tax\Helper\Data $taxData, \Magento\Tax\Model\Calculation $taxCalculation)
-    {
-        $this->taxData = $taxData;
-        $this->taxCalculation = $taxCalculation;
-    }
-
-    /**
-     * Get product price with all tax settings processing
-     *
-     * @param Product $_product
-     * @param float $_minimalPriceValue inputed product price
-     * @param bool $includingTax return price include tax flag
-     * @return float
-     */
-    public function getPrice($_product, $_minimalPriceValue, $includingTax = null)
-    {
-        return $this->taxData->getPrice($_product, $_minimalPriceValue, $includingTax);
-    }
-
-    /**
-     * Check if we have display in catalog prices including and excluding tax
-     *
-     * @return bool
-     */
-    public function displayBothPrices()
-    {
-        return $this->taxData->displayBothPrices();
-    }
-
-    /**
-     * Check if we have display in catalog prices including tax
-     *
-     * @return bool
-     */
-    public function displayPriceIncludingTax()
-    {
-        return $this->taxData->displayPriceIncludingTax();
-    }
-
-    /**
-     * Check if product prices on input include tax
-     *
-     * @return bool
-     */
-    public function priceIncludesTax()
-    {
-        return $this->taxData->priceIncludesTax();
-    }
-
-    /**
-     * Get customer data object
-     *
-     * @return Customer
-     */
-    public function getCustomer()
-    {
-        return $this->taxCalculation->getCustomerData();
-    }
-
-    /**
-     * Specify customer object which can be used for rate calculation
-     *
-     * @param Customer $customer
-     * @return $this
-     */
-    public function setCustomer(Customer $customer)
-    {
-        $this->taxCalculation->setCustomerData($customer);
-        return $this;
-    }
-
-    /**
-     * Get request object with information necessary for getting tax rate
-     *
-     * @param null|bool|\Magento\Framework\Object $shippingAddress
-     * @param null|bool||\Magento\Framework\Object $billingAddress
-     * @param null|int $customerTaxClass
-     * @param null|int $store
-     * @return \Magento\Framework\Object
-     */
-    public function getRateRequest(
-        $shippingAddress = null,
-        $billingAddress = null,
-        $customerTaxClass = null,
-        $store = null
-    ) {
-        return $this->taxCalculation->getRateRequest($shippingAddress, $billingAddress, $customerTaxClass, $store);
-    }
-
-    /**
-     * Get calculation tax rate by specific request
-     *
-     * @param \Magento\Framework\Object $request
-     * @return float
-     */
-    public function getRate($request)
-    {
-        return $this->taxCalculation->getRate($request);
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php
new file mode 100644
index 0000000000000000000000000000000000000000..b82bc3e5b36048bdafbe950ecc7be84449476a03
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product;
+
+class Eav implements \Magento\Indexer\Model\ActionInterface, \Magento\Framework\Mview\ActionInterface
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Row
+     */
+    protected $_productEavIndexerRow;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows
+     */
+    protected $_productEavIndexerRows;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full
+     */
+    protected $_productEavIndexerFull;
+
+    /**
+     * @param Eav\Action\Row $productEavIndexerRow
+     * @param Eav\Action\Rows $productEavIndexerRows
+     * @param Eav\Action\Full $productEavIndexerFull
+     */
+    public function __construct(
+        \Magento\Catalog\Model\Indexer\Product\Eav\Action\Row $productEavIndexerRow,
+        \Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows $productEavIndexerRows,
+        \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full $productEavIndexerFull
+    ) {
+        $this->_productEavIndexerRow = $productEavIndexerRow;
+        $this->_productEavIndexerRows = $productEavIndexerRows;
+        $this->_productEavIndexerFull = $productEavIndexerFull;
+    }
+
+    /**
+     * Execute materialization on ids entities
+     *
+     * @param int[] $ids
+     * @return void
+     */
+    public function execute($ids)
+    {
+        $this->_productEavIndexerRows->execute($ids);
+    }
+
+    /**
+     * Execute full indexation
+     *
+     * @return void
+     */
+    public function executeFull()
+    {
+        $this->_productEavIndexerFull->execute();
+    }
+
+    /**
+     * Execute partial indexation by ID list
+     *
+     * @param int[] $ids
+     * @return void
+     */
+    public function executeList($ids)
+    {
+        $this->_productEavIndexerRows->execute($ids);
+    }
+
+    /**
+     * Execute partial indexation by ID
+     *
+     * @param int $id
+     * @return void
+     */
+    public function executeRow($id)
+    {
+        $this->_productEavIndexerRow->execute($id);
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..453b93d0bbdd7bc3ac2b7cfcef60882fcd5fcf1f
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/AbstractAction.php
@@ -0,0 +1,117 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav;
+
+/**
+ * Abstract action reindex class
+ */
+abstract class AbstractAction
+{
+    /**
+     * EAV Indexers by type
+     *
+     * @var array
+     */
+    protected $_types;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory
+     */
+    protected $_eavSourceFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory
+     */
+    protected $_eavDecimalFactory;
+
+    /**
+     * @param \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory
+     * @param \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory $eavSourceFactory
+     */
+    public function __construct(
+        \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory $eavDecimalFactory,
+        \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory $eavSourceFactory
+    ) {
+        $this->_eavDecimalFactory = $eavDecimalFactory;
+        $this->_eavSourceFactory = $eavSourceFactory;
+    }
+
+    /**
+     * Execute action for given ids
+     *
+     * @param array|int $ids
+     * @return void
+     */
+    abstract public function execute($ids);
+
+    /**
+     * Retrieve array of EAV type indexers
+     *
+     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav[]
+     */
+    public function getIndexers()
+    {
+        if (is_null($this->_types)) {
+            $this->_types = array(
+                'source' => $this->_eavSourceFactory->create(),
+                'decimal' => $this->_eavDecimalFactory->create()
+            );
+        }
+
+        return $this->_types;
+    }
+
+    /**
+     * Retrieve indexer instance by type
+     *
+     * @param string $type
+     * @return \Magento\Catalog\Model\Resource\Product\Indexer\Eav\AbstractEav
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function getIndexer($type)
+    {
+        $indexers = $this->getIndexers();
+        if (!isset($indexers[$type])) {
+            throw new \Magento\Framework\Model\Exception(__('Unknown EAV indexer type "%1".', $type));
+        }
+        return $indexers[$type];
+    }
+
+    /**
+     * Reindex entities
+     *
+     * @param null|array|int $ids
+     * @return void
+     */
+    public function reindex($ids = null)
+    {
+        foreach ($this->getIndexers() as $indexer) {
+            if (is_null($ids)) {
+                $indexer->reindexAll();
+            } else {
+                $indexer->reindexEntities($ids);
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd6128e7dfb5da32e8fbccff04e824a2143f719d
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Full.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Class Full reindex action
+ */
+class Full extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
+{
+    /**
+     * Execute Full reindex
+     *
+     * @param array|int|null $ids
+     * @return void
+     * @throws \Magento\Catalog\Exception
+     */
+    public function execute($ids = null)
+    {
+        try {
+            $this->reindex();
+        } catch (\Exception $e) {
+            throw new \Magento\Catalog\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Row.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Row.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c9e2a0081cd478c4ee31f7c928ef63ef893af77
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Row.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Class Row reindex action
+ */
+class Row extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
+{
+    /**
+     * Execute Row reindex
+     *
+     * @param int|null $id
+     * @return void
+     * @throws \Magento\Catalog\Exception
+     */
+    public function execute($id = null)
+    {
+        if (!isset($id) || empty($id)) {
+            throw new \Magento\Catalog\Exception(__('Could not rebuild index for undefined product'));
+        }
+        try {
+            $this->reindex($id);
+        } catch (\Exception $e) {
+            throw new \Magento\Catalog\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Rows.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Rows.php
new file mode 100644
index 0000000000000000000000000000000000000000..87584b63b613ffe4cc2e2903fe934d3839c9920b
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Action/Rows.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Class Rows reindex action for mass actions
+ */
+class Rows extends \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction
+{
+    /**
+     * Execute Rows reindex
+     *
+     * @param array $ids
+     * @return void
+     * @throws \Magento\Catalog\Exception
+     */
+    public function execute($ids)
+    {
+        if (empty($ids)) {
+            throw new \Magento\Catalog\Exception(__('Bad value was supplied.'));
+        }
+        try {
+            $this->reindex($ids);
+        } catch (\Exception $e) {
+            throw new \Magento\Catalog\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet.php
new file mode 100644
index 0000000000000000000000000000000000000000..c4fe53fbea42e30cd3c1207f4c4e3383370ab397
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin;
+
+class AttributeSet
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_indexerEavProcessor;
+
+    /**
+     * @var AttributeSet\IndexableAttributeFilter
+     */
+    protected $_attributeFilter;
+
+    /**
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor
+     * @param AttributeSet\IndexableAttributeFilter $filter
+     */
+    public function __construct(
+        \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor,
+        AttributeSet\IndexableAttributeFilter $filter
+    ) {
+        $this->_indexerEavProcessor = $indexerEavProcessor;
+        $this->_attributeFilter = $filter;
+    }
+
+    /**
+     * Invalidate EAV indexer if attribute set has indexable attributes changes
+     *
+     * @param \Magento\Eav\Model\Entity\Attribute\Set $subject
+     * @param callable $proceed
+     *
+     * @return \Magento\Eav\Model\Entity\Attribute\Set
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function aroundSave(\Magento\Eav\Model\Entity\Attribute\Set $subject, \Closure $proceed)
+    {
+        $requiresReindex = false;
+        if ($subject->getId()) {
+            /** @var \Magento\Eav\Model\Entity\Attribute\Set $originalSet */
+            $originalSet = clone $subject;
+            $originalSet->initFromSkeleton($subject->getId());
+            $originalAttributeCodes = array_flip($this->_attributeFilter->filter($originalSet));
+            $subjectAttributeCodes = array_flip($this->_attributeFilter->filter($subject));
+            $requiresReindex = (bool)count(array_merge(
+                array_diff_key($subjectAttributeCodes, $originalAttributeCodes),
+                array_diff_key($originalAttributeCodes, $subjectAttributeCodes)
+            ));
+        }
+        $result = $proceed();
+        if ($requiresReindex) {
+            $this->_indexerEavProcessor->markIndexerAsInvalid();
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilter.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe08d6e044df68c692648588baa225cacf76f011
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilter.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet;
+
+
+class IndexableAttributeFilter
+{
+    /**
+     * @var \Magento\Catalog\Model\Resource\Eav\AttributeFactory
+     */
+    protected $_attributeFactory;
+
+    /**
+     * @param \Magento\Catalog\Model\Resource\Eav\AttributeFactory $attributeFactory
+     */
+    public function __construct(\Magento\Catalog\Model\Resource\Eav\AttributeFactory $attributeFactory)
+    {
+        $this->_attributeFactory = $attributeFactory;
+    }
+
+    /**
+     * Retrieve codes of indexable attributes from given attribute set
+     *
+     * @param \Magento\Eav\Model\Entity\Attribute\Set $set
+     * @return array
+     */
+    public function filter(\Magento\Eav\Model\Entity\Attribute\Set $set)
+    {
+        $codes = [];
+        $catalogResource = $this->_attributeFactory->create();
+
+        foreach ($set->getGroups() as $group) {
+            /** @var $group \Magento\Eav\Model\Entity\Attribute\Group */
+            foreach ($group->getAttributes() as $attribute) {
+                /** @var $attribute \Magento\Eav\Model\Entity\Attribute */
+                $catalogResource->load($attribute->getId());
+                if ($catalogResource->isIndexable()) {
+                    // Attribute requires to be cloned for new dataset to maintain attribute set changes
+                    $attributeClone = clone $attribute;
+                    $attributeClone->load($attribute->getAttributeId());
+                    $codes[] = $attributeClone->getAttributeCode();
+                    unset($attributeClone);
+                }
+            }
+        }
+        return $codes;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreView.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreView.php
new file mode 100644
index 0000000000000000000000000000000000000000..0551e54522f83992b60302faa3189d22f778f04a
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreView.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin;
+
+class StoreView
+{
+    /**
+     * Product attribute indexer processor
+     *
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_indexerEavProcessor;
+
+    /**
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor
+     */
+    public function __construct(\Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor)
+    {
+        $this->_indexerEavProcessor = $indexerEavProcessor;
+    }
+
+    /**
+     * Before save handler
+     *
+     * @param \Magento\Store\Model\Resource\Store $subject
+     * @param \Magento\Framework\Model\AbstractModel $object
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeSave(
+        \Magento\Store\Model\Resource\Store $subject,
+        \Magento\Framework\Model\AbstractModel $object
+    ) {
+        if ((!$object->getId() || $object->dataHasChangedFor('group_id')) && $object->getIsActive()) {
+            $this->_indexerEavProcessor->markIndexerAsInvalid();
+        }
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Processor.php b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Processor.php
new file mode 100644
index 0000000000000000000000000000000000000000..23c676961498aa33b0b26ad57264247291c7c31b
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Eav/Processor.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav;
+
+class Processor extends \Magento\Indexer\Model\Indexer\AbstractProcessor
+{
+    /**
+     * Indexer ID
+     */
+    const INDEXER_ID = 'catalog_product_attribute';
+}
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Processor.php b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Processor.php
index b4277d88f31684cbb439a1f75b3432a0d6e5a067..0a66b0a8a4505099c5c6b0b9cab74bc29f0b642f 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Processor.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Flat/Processor.php
@@ -23,18 +23,13 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product\Flat;
 
-class Processor
+class Processor extends \Magento\Indexer\Model\Indexer\AbstractProcessor
 {
     /**
      * Indexer ID
      */
     const INDEXER_ID = 'catalog_product_flat';
 
-    /**
-     * @var \Magento\Indexer\Model\IndexerInterface
-     */
-    protected $_indexer;
-
     /**
      * @var \Magento\Catalog\Model\Indexer\Product\Flat\State
      */
@@ -52,19 +47,6 @@ class Processor
         $this->_state = $state;
     }
 
-    /**
-     * Get indexer instance
-     *
-     * @return \Magento\Indexer\Model\Indexer
-     */
-    public function getIndexer()
-    {
-        if (!$this->_indexer->getId()) {
-            $this->_indexer->load(self::INDEXER_ID);
-        }
-        return $this->_indexer;
-    }
-
     /**
      * Reindex single row by id
      *
diff --git a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Processor.php b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Processor.php
index 7f11222c162eed82668b633078ee4d0ed4efcc7f..8343feb87f8a1a1b710b0530772754ba85210b10 100644
--- a/app/code/Magento/Catalog/Model/Indexer/Product/Price/Processor.php
+++ b/app/code/Magento/Catalog/Model/Indexer/Product/Price/Processor.php
@@ -23,85 +23,10 @@
  */
 namespace Magento\Catalog\Model\Indexer\Product\Price;
 
-class Processor
+class Processor extends \Magento\Indexer\Model\Indexer\AbstractProcessor
 {
     /**
      * Indexer ID
      */
     const INDEXER_ID = 'catalog_product_price';
-
-    /**
-     * @var \Magento\Indexer\Model\IndexerInterface
-     */
-    protected $_indexer;
-
-    /**
-     * @param \Magento\Indexer\Model\IndexerFactory $indexerFactory
-     */
-    public function __construct(
-        \Magento\Indexer\Model\IndexerFactory $indexerFactory
-    ) {
-        $this->_indexer = $indexerFactory->create();
-    }
-
-    /**
-     * Get indexer
-     *
-     * @return \Magento\Indexer\Model\IndexerInterface
-     */
-    public function getIndexer()
-    {
-        if (!$this->_indexer->getId()) {
-            $this->_indexer->load(self::INDEXER_ID);
-        }
-        return $this->_indexer;
-    }
-
-    /**
-     * Run Row reindex
-     *
-     * @param int $id
-     * @return void
-     */
-    public function reindexRow($id)
-    {
-        if ($this->getIndexer()->isScheduled()) {
-            return;
-        }
-        $this->getIndexer()->reindexRow($id);
-    }
-
-    /**
-     * Run List reindex
-     *
-     * @param int[] $ids
-     * @return void
-     */
-    public function reindexList($ids)
-    {
-        if ($this->getIndexer()->isScheduled()) {
-            return;
-        }
-        $this->getIndexer()->reindexList($ids);
-    }
-
-    /**
-     * Run Full reindex
-     *
-     * @return void
-     */
-    public function reindexAll()
-    {
-        $this->getIndexer()->reindexAll();
-    }
-
-    /**
-     * Mark Product price indexer as invalid
-     *
-     * @return void
-     */
-    public function markIndexerAsInvalid()
-    {
-        $this->getIndexer()->invalidate();
-    }
 }
diff --git a/app/code/Magento/Catalog/Model/Plugin/ShowOutOfStockConfig.php b/app/code/Magento/Catalog/Model/Plugin/ShowOutOfStockConfig.php
new file mode 100644
index 0000000000000000000000000000000000000000..54bd8c54de899b7f7498004b8f780d57aef1526c
--- /dev/null
+++ b/app/code/Magento/Catalog/Model/Plugin/ShowOutOfStockConfig.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Plugin;
+
+class ShowOutOfStockConfig
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_eavIndexerProcessor;
+
+    /**
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $eavIndexerProcessor
+     */
+    public function __construct(\Magento\Catalog\Model\Indexer\Product\Eav\Processor $eavIndexerProcessor)
+    {
+        $this->_eavIndexerProcessor = $eavIndexerProcessor;
+    }
+
+    /**
+     * After save handler
+     *
+     * @param \Magento\Framework\App\Config\Value $subject
+     * @param mixed $result
+     *
+     * @return mixed
+     */
+    public function afterSave(\Magento\Framework\App\Config\Value $subject, $result)
+    {
+        if ($subject->isValueChanged()) {
+            $this->_eavIndexerProcessor->markIndexerAsInvalid();
+        }
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Catalog/Model/Product.php b/app/code/Magento/Catalog/Model/Product.php
index 23aed6b00544498e2287ec004a978e25c3751235..7b467099e0ff21bea3bf6f4f80c3757b2931c07b 100644
--- a/app/code/Magento/Catalog/Model/Product.php
+++ b/app/code/Magento/Catalog/Model/Product.php
@@ -259,6 +259,11 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
      */
     protected $_productPriceIndexerProcessor;
 
+    /**
+     * @var Indexer\Product\Eav\Processor
+     */
+    protected $_productEavIndexerProcessor;
+
     /**
      * @var \Magento\Framework\Pricing\PriceInfo\Base
      */
@@ -289,6 +294,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
      * @param \Magento\Indexer\Model\IndexerInterface $categoryIndexer
      * @param Indexer\Product\Flat\Processor $productFlatIndexerProcessor
      * @param Indexer\Product\Price\Processor $productPriceIndexerProcessor
+     * @param  \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor
      * @param array $data
      *
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
@@ -318,6 +324,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         \Magento\Indexer\Model\IndexerInterface $categoryIndexer,
         \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
         \Magento\Catalog\Model\Indexer\Product\Price\Processor $productPriceIndexerProcessor,
+        \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
         array $data = array()
     ) {
         $this->_itemOptionFactory = $itemOptionFactory;
@@ -339,6 +346,7 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         $this->categoryIndexer = $categoryIndexer;
         $this->_productFlatIndexerProcessor = $productFlatIndexerProcessor;
         $this->_productPriceIndexerProcessor = $productPriceIndexerProcessor;
+        $this->_productEavIndexerProcessor = $productEavIndexerProcessor;
         parent::__construct($context, $registry, $storeManager, $resource, $resourceCollection, $data);
     }
 
@@ -731,7 +739,12 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         $this->getLinkInstance()->saveProductRelations($this);
         $this->getTypeInstance()->save($this);
 
+        if ($this->getStockData()) {
+            $this->setForceReindexEavRequired(true);
+        }
+
         $this->_getResource()->addCommitCallback(array($this, 'priceReindexCallback'));
+        $this->_getResource()->addCommitCallback(array($this, 'eavReindexCallback'));
 
         /**
          * Product Options
@@ -783,6 +796,18 @@ class Product extends \Magento\Catalog\Model\AbstractModel implements IdentityIn
         }
     }
 
+    /**
+     * Reindex callback for EAV indexer
+     *
+     * @return void
+     */
+    public function eavReindexCallback()
+    {
+        if ($this->isObjectNew() || $this->hasDataChanges()) {
+            $this->_productEavIndexerProcessor->reindexRow($this->getEntityId());
+        }
+    }
+
     /**
      * Init indexing process after product save
      *
diff --git a/app/code/Magento/Catalog/Model/Product/Action.php b/app/code/Magento/Catalog/Model/Product/Action.php
index 2d765f269e89d1d202013e84c71967989913b682..7eb6cd23108113059571ce1ad73807ca6cae0d56 100644
--- a/app/code/Magento/Catalog/Model/Product/Action.php
+++ b/app/code/Magento/Catalog/Model/Product/Action.php
@@ -49,12 +49,24 @@ class Action extends \Magento\Framework\Model\AbstractModel
      */
     protected $categoryIndexer;
 
+    /**
+     * @var \Magento\Eav\Model\Config
+     */
+    protected $_eavConfig;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_productEavIndexerProcessor;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Catalog\Model\Product\WebsiteFactory $productWebsiteFactory
      * @param \Magento\Index\Model\Indexer $indexIndexer
      * @param \Magento\Indexer\Model\IndexerInterface $categoryIndexer
+     * @param \Magento\Eav\Model\Config $eavConfig
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
@@ -65,6 +77,8 @@ class Action extends \Magento\Framework\Model\AbstractModel
         \Magento\Catalog\Model\Product\WebsiteFactory $productWebsiteFactory,
         \Magento\Index\Model\Indexer $indexIndexer,
         \Magento\Indexer\Model\IndexerInterface $categoryIndexer,
+        \Magento\Eav\Model\Config $eavConfig,
+        \Magento\Catalog\Model\Indexer\Product\Eav\Processor $productEavIndexerProcessor,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
@@ -72,6 +86,8 @@ class Action extends \Magento\Framework\Model\AbstractModel
         $this->_productWebsiteFactory = $productWebsiteFactory;
         $this->_indexIndexer = $indexIndexer;
         $this->categoryIndexer = $categoryIndexer;
+        $this->_eavConfig = $eavConfig;
+        $this->_productEavIndexerProcessor = $productEavIndexerProcessor;
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
     }
 
@@ -128,6 +144,10 @@ class Action extends \Magento\Framework\Model\AbstractModel
             array('product_ids' => array_unique($productIds), 'attributes_data' => $attrData, 'store_id' => $storeId)
         );
 
+        if ($this->_hasIndexableAttributes($attrData)) {
+            $this->_productEavIndexerProcessor->reindexList(array_unique($productIds));
+        }
+
         // register mass action indexer event
         $this->_indexIndexer->processEntityAction(
             $this,
@@ -140,6 +160,37 @@ class Action extends \Magento\Framework\Model\AbstractModel
         return $this;
     }
 
+    /**
+     * Attributes array has indexable attributes
+     *
+     * @param array $attributesData
+     * @return bool
+     */
+    protected function _hasIndexableAttributes($attributesData)
+    {
+        foreach ($attributesData as $code => $value) {
+            if ($this->_attributeIsIndexable($code)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Check is attribute indexable in EAV
+     *
+     * @param \Magento\Catalog\Model\Resource\Eav\Attribute|string $attribute
+     * @return bool
+     */
+    protected function _attributeIsIndexable($attribute)
+    {
+        if (!$attribute instanceof \Magento\Catalog\Model\Resource\Eav\Attribute) {
+            $attribute = $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attribute);
+        }
+
+        return $attribute->isIndexable();
+    }
+
     /**
      * Update websites for product action
      *
diff --git a/app/code/Magento/Catalog/Model/Product/Indexer/Eav.php b/app/code/Magento/Catalog/Model/Product/Indexer/Eav.php
deleted file mode 100644
index 316c0d24dc14ef060b5539930e04419e094f56ff..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Model/Product/Indexer/Eav.php
+++ /dev/null
@@ -1,294 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Model\Product\Indexer;
-
-/**
- * Catalog Product Eav Indexer Model
- *
- * @method \Magento\Catalog\Model\Resource\Product\Indexer\Eav _getResource()
- * @method \Magento\Catalog\Model\Resource\Product\Indexer\Eav getResource()
- * @method \Magento\Catalog\Model\Product\Indexer\Eav setEntityId(int $value)
- * @method int getAttributeId()
- * @method \Magento\Catalog\Model\Product\Indexer\Eav setAttributeId(int $value)
- * @method int getStoreId()
- * @method \Magento\Catalog\Model\Product\Indexer\Eav setStoreId(int $value)
- * @method int getValue()
- * @method \Magento\Catalog\Model\Product\Indexer\Eav setValue(int $value)
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Eav extends \Magento\Index\Model\Indexer\AbstractIndexer
-{
-    /**
-     * @var array
-     */
-    protected $_matchedEntities = array(
-        \Magento\Catalog\Model\Product::ENTITY => array(
-            \Magento\Index\Model\Event::TYPE_SAVE,
-            \Magento\Index\Model\Event::TYPE_DELETE,
-            \Magento\Index\Model\Event::TYPE_MASS_ACTION
-        ),
-        \Magento\Catalog\Model\Resource\Eav\Attribute::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE)
-    );
-
-    /**
-     * Eav config
-     *
-     * @var \Magento\Eav\Model\Config
-     */
-    protected $_eavConfig;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Eav\Model\Config $eavConfig
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Eav\Model\Config $eavConfig,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        $this->_eavConfig = $eavConfig;
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-    }
-
-    /**
-     * Retrieve Indexer name
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return __('Product Attributes');
-    }
-
-    /**
-     * Retrieve Indexer description
-     *
-     * @return string
-     */
-    public function getDescription()
-    {
-        return __('Index product attributes for layered navigation building');
-    }
-
-    /**
-     * Initialize resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\Catalog\Model\Resource\Product\Indexer\Eav');
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _registerEvent(\Magento\Index\Model\Event $event)
-    {
-        $entity = $event->getEntity();
-
-        if ($entity == \Magento\Catalog\Model\Product::ENTITY) {
-            switch ($event->getType()) {
-                case \Magento\Index\Model\Event::TYPE_DELETE:
-                    $this->_registerCatalogProductDeleteEvent($event);
-                    break;
-
-                case \Magento\Index\Model\Event::TYPE_SAVE:
-                    $this->_registerCatalogProductSaveEvent($event);
-                    break;
-
-                case \Magento\Index\Model\Event::TYPE_MASS_ACTION:
-                    $this->_registerCatalogProductMassActionEvent($event);
-                    break;
-            }
-        } else if ($entity == \Magento\Catalog\Model\Resource\Eav\Attribute::ENTITY) {
-            switch ($event->getType()) {
-                case \Magento\Index\Model\Event::TYPE_SAVE:
-                    $this->_registerCatalogAttributeSaveEvent($event);
-                    break;
-            }
-        }
-    }
-
-    /**
-     * Check is attribute indexable in EAV
-     *
-     * @param \Magento\Catalog\Model\Resource\Eav\Attribute|string $attribute
-     * @return bool
-     */
-    protected function _attributeIsIndexable($attribute)
-    {
-        if (!$attribute instanceof \Magento\Catalog\Model\Resource\Eav\Attribute) {
-            $attribute = $this->_eavConfig->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attribute);
-        }
-
-        return $attribute->isIndexable();
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerCatalogProductSaveEvent(\Magento\Index\Model\Event $event)
-    {
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $event->getDataObject();
-        $attributes = $product->getAttributes();
-        $reindexEav = $product->getForceReindexRequired();
-        foreach ($attributes as $attribute) {
-            $attributeCode = $attribute->getAttributeCode();
-            if ($this->_attributeIsIndexable($attribute) && $product->dataHasChangedFor($attributeCode)) {
-                $reindexEav = true;
-                break;
-            }
-        }
-
-        if ($reindexEav) {
-            $event->addNewData('reindex_eav', $reindexEav);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerCatalogProductDeleteEvent(\Magento\Index\Model\Event $event)
-    {
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $event->getDataObject();
-
-        $parentIds = $this->_getResource()->getRelationsByChild($product->getId());
-        if ($parentIds) {
-            $event->addNewData('reindex_eav_parent_ids', $parentIds);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Register data required by process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerCatalogProductMassActionEvent(\Magento\Index\Model\Event $event)
-    {
-        $reindexEav = false;
-
-        /* @var $actionObject \Magento\Framework\Object */
-        $actionObject = $event->getDataObject();
-        // check if attributes changed
-        $attrData = $actionObject->getAttributesData();
-        if (is_array($attrData)) {
-            foreach (array_keys($attrData) as $attributeCode) {
-                if ($this->_attributeIsIndexable($attributeCode)) {
-                    $reindexEav = true;
-                    break;
-                }
-            }
-        }
-
-        // check changed websites
-        if ($actionObject->getWebsiteIds()) {
-            $reindexEav = true;
-        }
-
-        // register affected products
-        if ($reindexEav) {
-            $event->addNewData('reindex_eav_product_ids', $actionObject->getProductIds());
-        }
-
-        return $this;
-    }
-
-    /**
-     * Register data required by process attribute save in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerCatalogAttributeSaveEvent(\Magento\Index\Model\Event $event)
-    {
-        /* @var $attribute \Magento\Catalog\Model\Resource\Eav\Attribute */
-        $attribute = $event->getDataObject();
-        if ($attribute->isIndexable()) {
-            $before = $attribute->getOrigData(
-                'is_filterable'
-            ) || $attribute->getOrigData(
-                'is_filterable_in_search'
-            ) || $attribute->getOrigData(
-                'is_visible_in_advanced_search'
-            );
-            $after = $attribute->getData(
-                'is_filterable'
-            ) || $attribute->getData(
-                'is_filterable_in_search'
-            ) || $attribute->getData(
-                'is_visible_in_advanced_search'
-            );
-
-            if (!$before && $after || $before && !$after) {
-                $event->addNewData('reindex_attribute', 1);
-                $event->addNewData('attribute_index_type', $attribute->getIndexType());
-                $event->addNewData('is_indexable', $after);
-            }
-        }
-
-        return $this;
-    }
-
-    /**
-     * Process event
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _processEvent(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (!empty($data['catalog_product_eav_reindex_all'])) {
-            $this->reindexAll();
-        }
-        if (empty($data['catalog_product_eav_skip_call_event_handler'])) {
-            $this->callEventHandler($event);
-        }
-    }
-}
diff --git a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
index 9294bf1dad7cc223a30ae9038effed73cdb36eba..e447bb073e5a717146b21d6db4094f07e5153095 100644
--- a/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
+++ b/app/code/Magento/Catalog/Model/Resource/Eav/Attribute.php
@@ -79,13 +79,6 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
 
     const ENTITY = 'catalog_eav_attribute';
 
-    /**
-     * Index indexer
-     *
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexIndexer;
-
     /**
      * @var LockValidatorInterface
      */
@@ -122,6 +115,11 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
      */
     protected $_productFlatIndexerHelper;
 
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_indexerEavProcessor;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -134,8 +132,8 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Catalog\Model\Product\ReservedAttributeList $reservedAttributeList
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
-     * @param \Magento\Index\Model\Indexer $indexIndexer
      * @param \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor
      * @param \Magento\Catalog\Helper\Product\Flat\Indexer $productFlatIndexerHelper
      * @param LockValidatorInterface $lockValidator
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -154,15 +152,15 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Catalog\Model\Product\ReservedAttributeList $reservedAttributeList,
         \Magento\Framework\Locale\ResolverInterface $localeResolver,
-        \Magento\Index\Model\Indexer $indexIndexer,
         \Magento\Catalog\Model\Indexer\Product\Flat\Processor $productFlatIndexerProcessor,
+        \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor,
         \Magento\Catalog\Helper\Product\Flat\Indexer $productFlatIndexerHelper,
         LockValidatorInterface $lockValidator,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
     ) {
-        $this->_indexIndexer = $indexIndexer;
+        $this->_indexerEavProcessor = $indexerEavProcessor;
         $this->_productFlatIndexerProcessor = $productFlatIndexerProcessor;
         $this->_productFlatIndexerHelper = $productFlatIndexerHelper;
         $this->attrLockValidator = $lockValidator;
@@ -238,33 +236,46 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
          */
         $this->_eavConfig->clear();
 
-        $enableBefore = $this->getOrigData(
-            'backend_type'
-        ) == 'static' || $this->_productFlatIndexerHelper->isAddFilterableAttributes() && $this->getOrigData(
-            'is_filterable'
-        ) > 0 || $this->getOrigData(
-            'used_in_product_listing'
-        ) == 1 || $this->getOrigData(
-            'used_for_sort_by'
-        ) == 1;
-        $enableAfter = $this->getData(
-            'backend_type'
-        ) == 'static' || $this->_productFlatIndexerHelper->isAddFilterableAttributes() && $this->getData(
-            'is_filterable'
-        ) > 0 || $this->getData(
-            'used_in_product_listing'
-        ) == 1 || $this->getData(
-            'used_for_sort_by'
-        ) == 1;
-
-        if ($enableBefore != $enableAfter) {
+        if ($this->_isOriginalEnabledInFlat() != $this->_isEnabledInFlat()) {
             $this->_productFlatIndexerProcessor->markIndexerAsInvalid();
         }
+        if ($this->_isOriginalIndexable() !== $this->isIndexable()
+            || ($this->isIndexable() && $this->dataHasChangedFor('is_global'))
+        ) {
+            $this->_indexerEavProcessor->markIndexerAsInvalid();
+        }
 
-        $this->_indexIndexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
         return parent::_afterSave();
     }
 
+    /**
+     * Is attribute enabled for flat indexing
+     *
+     * @return bool
+     */
+    protected function _isEnabledInFlat()
+    {
+        return $this->getData('backend_type') == 'static'
+        || $this->_productFlatIndexerHelper->isAddFilterableAttributes()
+        && $this->getData('is_filterable') > 0
+        || $this->getData('used_in_product_listing') == 1
+        || $this->getData('used_for_sort_by') == 1;
+    }
+
+    /**
+     * Is original attribute enabled for flat indexing
+     *
+     * @return bool
+     */
+    protected function _isOriginalEnabledInFlat()
+    {
+        return $this->getOrigData('backend_type') == 'static'
+        || $this->_productFlatIndexerHelper->isAddFilterableAttributes()
+        && $this->getOrigData('is_filterable') > 0
+        || $this->getOrigData('used_in_product_listing') == 1
+        || $this->getOrigData('used_for_sort_by') == 1;
+    }
+
     /**
      * Register indexing event before delete catalog eav attribute
      *
@@ -274,7 +285,6 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
     protected function _beforeDelete()
     {
         $this->attrLockValidator->validate($this);
-        $this->_indexIndexer->logEvent($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_DELETE);
         return parent::_beforeDelete();
     }
 
@@ -287,9 +297,12 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
     {
         parent::_afterDeleteCommit();
 
-        $this->_productFlatIndexerProcessor->markIndexerAsInvalid();
-
-        $this->_indexIndexer->indexEvents(self::ENTITY, \Magento\Index\Model\Event::TYPE_DELETE);
+        if ($this->_isOriginalEnabledInFlat()) {
+            $this->_productFlatIndexerProcessor->markIndexerAsInvalid();
+        }
+        if ($this->_isOriginalIndexable()) {
+            $this->_indexerEavProcessor->markIndexerAsInvalid();
+        }
         return $this;
     }
 
@@ -442,6 +455,38 @@ class Attribute extends \Magento\Eav\Model\Entity\Attribute
         return false;
     }
 
+    /**
+     * Is original attribute config indexable
+     *
+     * @return bool
+     */
+    protected function _isOriginalIndexable()
+    {
+        // exclude price attribute
+        if ($this->getOrigData('attribute_code') == 'price') {
+            return false;
+        }
+
+        if (!$this->getOrigData('is_filterable_in_search')
+            && !$this->getOrigData('is_visible_in_advanced_search')
+            && !$this->getOrigData('is_filterable')) {
+            return false;
+        }
+
+        $backendType = $this->getOrigData('backend_type');
+        $frontendInput = $this->getOrigData('frontend_input');
+
+        if ($backendType == 'int' && $frontendInput == 'select') {
+            return true;
+        } else if ($backendType == 'varchar' && $frontendInput == 'multiselect') {
+            return true;
+        } else if ($backendType == 'decimal') {
+            return true;
+        }
+
+        return false;
+    }
+
     /**
      * Retrieve index type for indexable attribute
      *
diff --git a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
index ec2c1790c750ae30570e603b967e6659ee59d064..1c5d1ba46ad8d0e4c32ce11727903e31f7c7f67c 100644
--- a/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
+++ b/app/code/Magento/Catalog/Pricing/Price/BasePrice.php
@@ -47,7 +47,7 @@ class BasePrice extends AbstractPrice
         if ($this->value === null) {
             $this->value = false;
             foreach ($this->priceInfo->getPrices() as $price) {
-                if ($price instanceof BasePriceProviderInterface && $price->getValue()) {
+                if ($price instanceof BasePriceProviderInterface && $price->getValue() !== false) {
                     $this->value = min($price->getValue(), $this->value ? : $price->getValue());
                 }
             }
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Product/Attribute/SearchResultsBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/Product/Attribute/SearchResultsBuilder.php
index dda2b0bbd8186db5e331db33bdf344b362711ee5..bca9e55cac657441fa18473a67d92d4ae0de7a26 100644
--- a/app/code/Magento/Catalog/Service/V1/Data/Product/Attribute/SearchResultsBuilder.php
+++ b/app/code/Magento/Catalog/Service/V1/Data/Product/Attribute/SearchResultsBuilder.php
@@ -41,14 +41,14 @@ class SearchResultsBuilder extends \Magento\Framework\Service\V1\Data\AbstractSe
      *
      * @param ObjectFactory $objectFactory
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
-     * @param AttributeBuilder $attributeBuilder
+     * @param AttributeBuilder $itemObjectBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
         SearchCriteriaBuilder $searchCriteriaBuilder,
-        AttributeBuilder $attributeBuilder
+        AttributeBuilder $itemObjectBuilder
     ) {
-        parent::__construct($objectFactory, $searchCriteriaBuilder, $attributeBuilder);
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $itemObjectBuilder);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Service/V1/Data/Product/SearchResultsBuilder.php b/app/code/Magento/Catalog/Service/V1/Data/Product/SearchResultsBuilder.php
index 914a5be932afa37c4f41523ba1f0356d9760b10b..0e6fff2558aa6f349bce1a68cf570ceb2ede33ed 100644
--- a/app/code/Magento/Catalog/Service/V1/Data/Product/SearchResultsBuilder.php
+++ b/app/code/Magento/Catalog/Service/V1/Data/Product/SearchResultsBuilder.php
@@ -41,14 +41,14 @@ class SearchResultsBuilder extends AbstractSearchResultsBuilder
      *
      * @param ObjectFactory $objectFactory
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
-     * @param ProductBuilder $productBuilder
+     * @param ProductBuilder $itemObjectBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
         SearchCriteriaBuilder $searchCriteriaBuilder,
-        ProductBuilder $productBuilder
+        ProductBuilder $itemObjectBuilder
     ) {
-        parent::__construct($objectFactory, $searchCriteriaBuilder, $productBuilder);
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $itemObjectBuilder);
     }
 
     /**
diff --git a/app/code/Magento/Catalog/etc/adminhtml/routes.xml b/app/code/Magento/Catalog/etc/adminhtml/routes.xml
index 570765a51933b3776410e63d4c93a22a01341da9..0067221bf249423047a748f6f1ded54efaf8f76b 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="catalog" frontName="catalog">
-            <module name="Magento_Catalog_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_Catalog" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/Catalog/etc/di.xml b/app/code/Magento/Catalog/etc/di.xml
index 251634993449a64df57cc9d7d7b3ac91a059bfde..feb24c8bfa8b28c403839f159aa96841f7dab540 100644
--- a/app/code/Magento/Catalog/etc/di.xml
+++ b/app/code/Magento/Catalog/etc/di.xml
@@ -199,6 +199,7 @@
         <plugin name="storeViewResourceAroundSave" type="Magento\Catalog\Model\Indexer\Category\Flat\Plugin\StoreView"/>
         <plugin name="catalogProductFlatIndexerStore" type="Magento\Catalog\Model\Indexer\Product\Flat\Plugin\Store" />
         <plugin name="categoryStoreAroundSave" type="Magento\Catalog\Model\Indexer\Category\Product\Plugin\StoreView"/>
+        <plugin name="productAttributesStoreViewSave" type="Magento\Catalog\Model\Indexer\Product\Eav\Plugin\StoreView"/>
     </type>
     <type name="Magento\Store\Model\Resource\Group">
         <plugin name="storeGroupResourceAroundSave" type="Magento\Catalog\Model\Indexer\Category\Flat\Plugin\StoreGroup"/>
@@ -239,6 +240,9 @@
             <argument name="indexer" xsi:type="object" shared="false">Magento\Indexer\Model\IndexerInterface</argument>
         </arguments>
     </type>
+    <type name="Magento\Eav\Model\Entity\Attribute\Set">
+        <plugin name="invalidateEavIndexerOnAttributeSetSave" type="\Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet" />
+    </type>
     <type name="Magento\CatalogRule\Model\Rule">
         <plugin name="reindexPriceOnRuleApply" type="\Magento\Catalog\Model\Indexer\Product\Price\Plugin\CatalogRule" />
     </type>
@@ -465,4 +469,7 @@
             <argument name="searchResultsBuilder" xsi:type="object" shared="false">Magento\Catalog\Service\V1\Data\Product\SearchResultsBuilder</argument>
         </arguments>
     </type>
+    <type name="Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock">
+        <plugin name="showOutOfStockValueChanged" type="\Magento\Catalog\Model\Plugin\ShowOutOfStockConfig"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Catalog/etc/indexer.xml b/app/code/Magento/Catalog/etc/indexer.xml
index 114be80d54823cccd9029b2a810238e38e909039..2e368f17a8b428251fb65da6758850b6dfcc2d6e 100644
--- a/app/code/Magento/Catalog/etc/indexer.xml
+++ b/app/code/Magento/Catalog/etc/indexer.xml
@@ -44,4 +44,8 @@
         <title translate="true">Product Price</title>
         <description translate="true">Index product prices</description>
     </indexer>
+    <indexer id="catalog_product_attribute" view_id="catalog_product_attribute" class="Magento\Catalog\Model\Indexer\Product\Eav">
+        <title translate="true">Product EAV</title>
+        <description translate="true">Index product EAV</description>
+    </indexer>
 </config>
diff --git a/app/code/Magento/Catalog/etc/indexers.xml b/app/code/Magento/Catalog/etc/indexers.xml
index e70454f5ef026466fed7bc950217fabd586f01b1..52135bd75d703ed6c5d9914199ede423fde24f8f 100644
--- a/app/code/Magento/Catalog/etc/indexers.xml
+++ b/app/code/Magento/Catalog/etc/indexers.xml
@@ -24,6 +24,5 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Index/etc/indexers.xsd">
-    <indexer name="catalog_product_attribute" instance="Magento\Catalog\Model\Product\Indexer\Eav" />
     <indexer name="catalog_url" instance="Magento\Catalog\Model\Indexer\Url" />
 </config>
diff --git a/app/code/Magento/Catalog/etc/module.xml b/app/code/Magento/Catalog/etc/module.xml
index dbd9e2cec081db72e05c6e7cc341d47371503690..991c1e63bfc736bfb28d33d0d73e616faf39594e 100644
--- a/app/code/Magento/Catalog/etc/module.xml
+++ b/app/code/Magento/Catalog/etc/module.xml
@@ -24,7 +24,7 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
-    <module name="Magento_Catalog" schema_version="1.6.0.0.26" active="true">
+    <module name="Magento_Catalog" schema_version="1.6.0.0.27" active="true">
         <sequence>
             <module name="Magento_Eav"/>
             <module name="Magento_Cms"/>
diff --git a/app/code/Magento/Catalog/etc/mview.xml b/app/code/Magento/Catalog/etc/mview.xml
index c946a57c53e60bc4ab7d4e100fd22bde6d24f302..302d5f46dffbfddc3627188c5b1efda35f87db27 100644
--- a/app/code/Magento/Catalog/etc/mview.xml
+++ b/app/code/Magento/Catalog/etc/mview.xml
@@ -71,4 +71,11 @@
             <table name="catalog_product_entity_tier_price" entity_column="entity_id" />
         </subscriptions>
     </view>
+    <view id="catalog_product_attribute" class="Magento\Catalog\Model\Indexer\Product\Eav" group="indexer">
+        <subscriptions>
+            <table name="catalog_product_entity_decimal" entity_column="entity_id" />
+            <table name="catalog_product_entity_int" entity_column="entity_id" />
+            <table name="catalog_product_entity_varchar" entity_column="entity_id" />
+        </subscriptions>
+    </view>
 </config>
diff --git a/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.26-1.6.0.0.27.php b/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.26-1.6.0.0.27.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee142dd7d99904ddf78eb87cc06c8acc9cf83044
--- /dev/null
+++ b/app/code/Magento/Catalog/sql/catalog_setup/upgrade-1.6.0.0.26-1.6.0.0.27.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $this \Magento\Eav\Model\Entity\Setup */
+
+$this->startSetup();
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav'),
+    $this->getFkName('catalog_product_index_eav', 'attribute_id', 'eav_attribute', 'attribute_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav'),
+    $this->getFkName('catalog_product_index_eav', 'entity_id', 'catalog_product_entity', 'entity_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav'),
+    $this->getFkName('catalog_product_index_eav', 'store_id', 'store', 'store_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav_decimal'),
+    $this->getFkName('catalog_product_index_eav_decimal', 'attribute_id', 'eav_attribute', 'attribute_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav_decimal'),
+    $this->getFkName('catalog_product_index_eav_decimal', 'entity_id', 'catalog_product_entity', 'entity_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('catalog_product_index_eav_decimal'),
+    $this->getFkName('catalog_product_index_eav_decimal', 'store_id', 'store', 'store_id')
+);
+
+$this->endSetup();
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/js.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/js.phtml
index ff66f817e871f870807ba062933b02eb4248ca24..5f3d3069e5fbc71d4ade022f407dea3a40d01232 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/js.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/js.phtml
@@ -21,6 +21,8 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
+
+/** @var \Magento\Catalog\Block\Adminhtml\Product\Edit\Js $this */
 ?>
 <script type="text/javascript">
 //<![CDATA[
@@ -39,7 +41,7 @@ function registerTaxRecalcs() {
 }
 
 var priceFormat = <?php echo $this->helper('Magento\Tax\Helper\Data')->getPriceFormat($this->getStore()); ?>;
-var taxRates = <?php echo $this->helper('Magento\Tax\Helper\Data')->getAllRatesByProductClass($this->getStore()); ?>;
+var taxRates = <?php echo $this->getAllRatesByProductClassJson(); ?>;
 
 function recalculateTax() {
     if (typeof dynamicTaxes == 'undefined') {
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/price.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/price.phtml
index 9572daa5373748fd8a97309fed7510a1b842fcc4..9f5f6a91e3a8e1abfaac37801fc9e0f69465952b 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/price.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/price.phtml
@@ -35,8 +35,8 @@
     $_coreHelper        = $this->helper('Magento\Core\Helper\Data');
     /** @var $weeeHelper \Magento\Weee\Helper\Data */
     $weeeHelper        = $this->helper('Magento\Weee\Helper\Data');
-    /** @var $priceHelper \Magento\Catalog\Helper\Product\Price */
-    $priceHelper         = $this->helper('Magento\Catalog\Helper\Product\Price');
+    /** @var $taxHelper \Magento\Tax\Helper\Data */
+    $taxHelper         = $this->helper('Magento\Tax\Helper\Data');
 
     $_product           = $this->getProduct();
     $_id                = $_product->getId();
@@ -44,15 +44,15 @@
     $_website           = $this->getWebsite($_storeId);
 
     $_weeeSeparator     = '';
-    $_simplePricesTax   = ($priceHelper->displayPriceIncludingTax() || $priceHelper->displayBothPrices());
+    $_simplePricesTax   = ($taxHelper->displayPriceIncludingTax() || $taxHelper->displayBothPrices());
     $_minimalPriceValue = $_product->getMinimalPrice();
-    $_minimalPrice      = $priceHelper->getPrice($_product, $_minimalPriceValue, $_simplePricesTax);
+    $_minimalPrice      = $taxHelper->getPrice($_product, $_minimalPriceValue, $_simplePricesTax);
 ?>
 
 
 <?php
-$_exclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax = null);
-$_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax = true);
+$_exclTax = $taxHelper->getPrice($_product, $_minimalPriceValue, $includingTax = null);
+$_inclTax = $taxHelper->getPrice($_product, $_minimalPriceValue, $includingTax = true);
 ?>
 <?php $_weeeTaxAmount = $weeeHelper->getAmount($_product, $_website); ?>
 <?php if ($weeeHelper->typeOfDisplay(array(1,2,4))): ?>
@@ -61,13 +61,13 @@ $_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax
 <?php endif; ?>
 
 <div class="price-box">
-<?php $_price = $priceHelper->getPrice($_product, $_product->getPrice()) ?>
-<?php $_regularPrice = $priceHelper->getPrice($_product, $_product->getPrice(), $_simplePricesTax) ?>
-<?php $_finalPrice = $priceHelper->getPrice($_product, $_product->getFinalPrice()) ?>
-<?php $_finalPriceInclTax = $priceHelper->getPrice($_product, $_product->getFinalPrice(), true) ?>
+<?php $_price = $taxHelper->getPrice($_product, $_product->getPrice()) ?>
+<?php $_regularPrice = $taxHelper->getPrice($_product, $_product->getPrice(), $_simplePricesTax) ?>
+<?php $_finalPrice = $taxHelper->getPrice($_product, $_product->getFinalPrice()) ?>
+<?php $_finalPriceInclTax = $taxHelper->getPrice($_product, $_product->getFinalPrice(), true) ?>
 <?php $_weeeDisplayType = $weeeHelper->getPriceDisplayType(); ?>
 <?php if ($_finalPrice == $_price): ?>
-    <?php if ($priceHelper->displayBothPrices()): ?>
+    <?php if ($taxHelper->displayBothPrices()): ?>
         <?php if ($_weeeTaxAmount && $weeeHelper->typeOfDisplay(0)): // including ?>
             <span class="price-excluding-tax">
                 <span class="label"><?php echo __('Excl. Tax:') ?></span>
@@ -207,7 +207,7 @@ $_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax
             </span>
         </p>
 
-        <?php if ($priceHelper->displayBothPrices()): ?>
+        <?php if ($taxHelper->displayBothPrices()): ?>
             <p class="special-price">
                 <span class="price-label"><?php echo __('Special Price:') ?></span>
                 <span class="price-excluding-tax">
@@ -328,7 +328,7 @@ $_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax
             </span>
         </p>
 
-        <?php if ($priceHelper->displayBothPrices()): ?>
+        <?php if ($taxHelper->displayBothPrices()): ?>
             <p class="special-price">
                 <span class="price-label"><?php echo __('Special Price:') ?></span>
                 <span class="price-excluding-tax">
diff --git a/app/code/Magento/Catalog/view/frontend/templates/rss/product/price.phtml b/app/code/Magento/Catalog/view/frontend/templates/rss/product/price.phtml
index 35c7e81d42d525aa0d7cc8e9b86a9f20283194a9..55f0ea599f6d6f11b00af2fa22d21c9e6137e7ff 100644
--- a/app/code/Magento/Catalog/view/frontend/templates/rss/product/price.phtml
+++ b/app/code/Magento/Catalog/view/frontend/templates/rss/product/price.phtml
@@ -31,15 +31,15 @@
  */
 ?>
 <?php $_product = $this->getProduct() ?>
-<?php /* @var $priceHelper \Magento\Catalog\Helper\Product\Price */ ?>
+<?php /* @var $taxHelper \Magento\Tax\Helper\Data */ ?>
 <?php $_id = $_product->getId() ?>
-<?php $priceHelper = $this->helper('Magento\Catalog\Helper\Product\Price'); ?>
+<?php $taxHelper = $this->helper('Magento\Tax\Helper\Data'); ?>
 <?php if ($_product->getCanShowPrice() !== false):?>
 
     <?php $_weeeSeparator = ''; ?>
-    <?php $simplePricesTax = ($priceHelper->displayPriceIncludingTax() || $priceHelper->displayBothPrices()); ?>
+    <?php $simplePricesTax = ($taxHelper->displayPriceIncludingTax() || $taxHelper->displayBothPrices()); ?>
     <?php $_minimalPriceValue = $_product->getMinimalPrice() ?>
-    <?php $_minimalPrice = $priceHelper->getPrice($_product, $_minimalPriceValue, $simplePricesTax) ?>
+    <?php $_minimalPrice = $taxHelper->getPrice($_product, $_minimalPriceValue, $simplePricesTax) ?>
 
     <?php $_weeeTaxAmount = $this->helper('Magento\Weee\Helper\Data')->getAmountForDisplay($_product); ?>
     <?php if ($this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(array(1,2,4))): ?>
@@ -48,13 +48,13 @@
     <?php endif; ?>
 
     <div class="price-box">
-    <?php $_price = $priceHelper->getPrice($_product, $_product->getPrice()) ?>
-    <?php $_regularPrice = $priceHelper->getPrice($_product, $_product->getPrice(), $simplePricesTax) ?>
-    <?php $_finalPrice = $priceHelper->getPrice($_product, $_product->getFinalPrice()) ?>
-    <?php $_finalPriceInclTax = $priceHelper->getPrice($_product, $_product->getFinalPrice(), true) ?>
+    <?php $_price = $taxHelper->getPrice($_product, $_product->getPrice()) ?>
+    <?php $_regularPrice = $taxHelper->getPrice($_product, $_product->getPrice(), $simplePricesTax) ?>
+    <?php $_finalPrice = $taxHelper->getPrice($_product, $_product->getFinalPrice()) ?>
+    <?php $_finalPriceInclTax = $taxHelper->getPrice($_product, $_product->getFinalPrice(), true) ?>
     <?php $_weeeDisplayType = $this->helper('Magento\Weee\Helper\Data')->getPriceDisplayType(); ?>
     <?php if ($_finalPrice == $_price): ?>
-        <?php if ($priceHelper->displayBothPrices()): ?>
+        <?php if ($taxHelper->displayBothPrices()): ?>
             <?php if ($_weeeTaxAmount && $this->helper('Magento\Weee\Helper\Data')->typeOfDisplay(0)): // including ?>
                 <span class="price-excluding-tax">
                     <span class="label"><?php echo __('Excl. Tax:') ?></span>
@@ -172,7 +172,7 @@
                 <span class="price" id="old-price-<?php echo $_id ?><?php echo $this->getIdSuffix() ?>"><?php echo $this->helper('Magento\Core\Helper\Data')->currency($_regularPrice+$_originalWeeeTaxAmount,true,false) ?></span>
             </p>
 
-            <?php if ($priceHelper->displayBothPrices()): ?>
+            <?php if ($taxHelper->displayBothPrices()): ?>
                 <p class="special-price">
                     <span class="price-label"><?php echo __('Special Price:') ?></span>
                     <span class="price-excluding-tax">
@@ -272,7 +272,7 @@
                 <span class="price" id="old-price-<?php echo $_id ?><?php echo $this->getIdSuffix() ?>"><?php echo $this->helper('Magento\Core\Helper\Data')->currency($_regularPrice,true,false) ?></span>
             </p>
 
-            <?php if ($priceHelper->displayBothPrices()): ?>
+            <?php if ($taxHelper->displayBothPrices()): ?>
                 <p class="special-price">
                     <span class="price-label"><?php echo __('Special Price:') ?></span>
                     <span class="price-excluding-tax">
diff --git a/app/code/Magento/CatalogImportExport/Model/Import/Product.php b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
index 2b13d13262967b509844a4e543e2f2e6101e5ef2..0562b37b7362373f62f8a4c120dc2658145c21f6 100644
--- a/app/code/Magento/CatalogImportExport/Model/Import/Product.php
+++ b/app/code/Magento/CatalogImportExport/Model/Import/Product.php
@@ -474,11 +474,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      */
     protected $dateTime;
 
-    /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $indexer;
-
     /**
      * @var \Magento\Indexer\Model\Indexer
      */
@@ -522,7 +517,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
      * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
      * @param \Magento\Framework\Stdlib\DateTime $dateTime
      * @param \Magento\Framework\Logger $logger
-     * @param \Magento\Index\Model\Indexer $indexer
      * @param \Magento\Indexer\Model\Indexer $newIndexer
      * @param array $data
      */
@@ -554,7 +548,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
         \Magento\Framework\Stdlib\DateTime $dateTime,
         \Magento\Framework\Logger $logger,
-        \Magento\Index\Model\Indexer $indexer,
         \Magento\Indexer\Model\Indexer $newIndexer,
         array $data = array()
     ) {
@@ -576,7 +569,6 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
         $this->_stockResItemFac = $stockResItemFac;
         $this->_localeDate = $localeDate;
         $this->dateTime = $dateTime;
-        $this->indexer = $indexer;
         $this->newIndexer = $newIndexer;
         $this->_logger = $logger;
         parent::__construct($coreData, $importExportData, $importData, $config, $resource, $resourceHelper, $string);
@@ -1793,6 +1785,8 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
                     $row
                 );
 
+                $row = $this->stockItemService->processIsInStock($row);
+
                 if ($this->stockItemService->isQty($this->_newSku[$rowData[self::COL_SKU]]['type_id'])) {
                     if ($this->stockItemService->verifyNotification($row['product_id'])) {
                         $row['low_stock_date'] = $this->_localeDate->date(
@@ -1817,10 +1811,7 @@ class Product extends \Magento\ImportExport\Model\Import\Entity\AbstractEntity
             }
 
             if ($productIdsToReindex) {
-                $this->indexer->getProcessByCode('cataloginventory_stock')->getIndexer()->reindexAll();
-                $this->indexer->getProcessByCode('catalog_product_attribute')->getIndexer()->reindexAll();
                 $this->newIndexer->load('catalog_product_category')->reindexList($productIdsToReindex);
-                $this->newIndexer->load('catalog_product_price')->reindexList($productIdsToReindex);
             }
         }
         return $this;
diff --git a/app/code/Magento/CatalogImportExport/Model/Indexer/Product/Eav/Plugin/Import.php b/app/code/Magento/CatalogImportExport/Model/Indexer/Product/Eav/Plugin/Import.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe44d0f52977f6af54d9903da2446f60706844d5
--- /dev/null
+++ b/app/code/Magento/CatalogImportExport/Model/Indexer/Product/Eav/Plugin/Import.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogImportExport\Model\Indexer\Product\Eav\Plugin;
+
+class Import
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_indexerEavProcessor;
+
+    /**
+     * @param \Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor
+     */
+    public function __construct(\Magento\Catalog\Model\Indexer\Product\Eav\Processor $indexerEavProcessor)
+    {
+        $this->_indexerEavProcessor = $indexerEavProcessor;
+    }
+
+    /**
+     * After import handler
+     *
+     * @param \Magento\ImportExport\Model\Import $subject
+     * @param Object $import
+     *
+     * @return mixed
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function afterImportSource(\Magento\ImportExport\Model\Import $subject, $import)
+    {
+        $this->_indexerEavProcessor->markIndexerAsInvalid();
+        return $import;
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/CustomerTaxClass.php b/app/code/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/Import.php
similarity index 54%
rename from app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/CustomerTaxClass.php
rename to app/code/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/Import.php
index 82160297fca03e0954c58e9d1b3e59dacfc9e6fa..b98ef30c07d4a40946f19411324028181510e8ff 100644
--- a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/CustomerTaxClass.php
+++ b/app/code/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/Import.php
@@ -1,7 +1,5 @@
 <?php
 /**
- * Customer Tax Class option array
- *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -23,32 +21,35 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Tax\Model\Resource\Rule\Grid\Options;
+namespace Magento\CatalogImportExport\Model\Indexer\Stock\Plugin;
 
-class CustomerTaxClass implements \Magento\Framework\Option\ArrayInterface
+class Import
 {
     /**
-     * @var \Magento\Tax\Model\Resource\TaxClass\CollectionFactory
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
      */
-    protected $_collectionFactory;
+    protected $_stockndexerProcessor;
 
     /**
-     * @param \Magento\Tax\Model\Resource\TaxClass\CollectionFactory $collectionFactory
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockndexerProcessor
      */
-    public function __construct(\Magento\Tax\Model\Resource\TaxClass\CollectionFactory $collectionFactory)
+    public function __construct(\Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockndexerProcessor)
     {
-        $this->_collectionFactory = $collectionFactory;
+        $this->_stockndexerProcessor = $stockndexerProcessor;
     }
 
     /**
-     * Return Customer Tax Class array
+     * After import handler
+     *
+     * @param \Magento\ImportExport\Model\Import $subject
+     * @param Object $import
      *
-     * @return array
+     * @return mixed
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function toOptionArray()
+    public function afterImportSource(\Magento\ImportExport\Model\Import $subject, $import)
     {
-        return $this->_collectionFactory->create()->setClassTypeFilter(
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER
-        )->toOptionHash();
+        $this->_stockndexerProcessor->markIndexerAsInvalid();
+        return $import;
     }
 }
diff --git a/app/code/Magento/CatalogImportExport/etc/di.xml b/app/code/Magento/CatalogImportExport/etc/di.xml
index 3b23b8aa68751a0685fd6926fd05d9e86c4b918d..467acd5938d53a701fd73ba9a3222bb6d7093a71 100644
--- a/app/code/Magento/CatalogImportExport/etc/di.xml
+++ b/app/code/Magento/CatalogImportExport/etc/di.xml
@@ -28,6 +28,8 @@
     <type name="Magento\ImportExport\Model\Import">
         <plugin name="catalogProductFlatIndexerImport" type="\Magento\CatalogImportExport\Model\Indexer\Product\Flat\Plugin\Import" />
         <plugin name="invalidatePriceIndexerOnImport" type="\Magento\CatalogImportExport\Model\Indexer\Product\Price\Plugin\Import" />
+        <plugin name="invalidateStockIndexerOnImport" type="\Magento\CatalogImportExport\Model\Indexer\Stock\Plugin\Import" />
+        <plugin name="invalidateEavIndexerOnImport" type="\Magento\CatalogImportExport\Model\Indexer\Product\Eav\Plugin\Import" />
     </type>
     <type name="Magento\CatalogImportExport\Model\Export\RowCustomizer\Composite">
         <arguments>
diff --git a/app/code/Magento/CatalogImportExport/etc/module.xml b/app/code/Magento/CatalogImportExport/etc/module.xml
index 1bf9a1ca0174c510177f65376befeb72b85517ba..f4dfd26b5d984ebbeb5ae3bdb769ba5a11e04ab4 100644
--- a/app/code/Magento/CatalogImportExport/etc/module.xml
+++ b/app/code/Magento/CatalogImportExport/etc/module.xml
@@ -30,7 +30,6 @@
             <module name="Magento_Catalog"/>
             <module name="Magento_Eav"/>
             <module name="Magento_ImportExport"/>
-            <module name="Magento_Index"/>
             <module name="Magento_Indexer"/>
             <module name="Magento_Store"/>
             <module name="Magento_CatalogInventory"/>
diff --git a/app/code/Magento/CatalogInventory/Exception.php b/app/code/Magento/CatalogInventory/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d617eeaaab9bf7fb432916da68fd17bf3704421
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Exception.php
@@ -0,0 +1,28 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogInventory;
+
+class Exception extends \Exception
+{
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/AbstractValue.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/AbstractValue.php
new file mode 100644
index 0000000000000000000000000000000000000000..28294ca9eda5e9a9d45cc20b09dfcd80513663a0
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/AbstractValue.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Catalog Inventory Config Backend Model
+ */
+namespace Magento\CatalogInventory\Model\Config\Backend;
+
+abstract class AbstractValue extends \Magento\Framework\App\Config\Value
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Stock\Status
+     */
+    protected $_stockStatus;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_stockIndexerProcessor;
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
+     * @param \Magento\CatalogInventory\Model\Stock\Status $stockStatus
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\App\Config\ScopeConfigInterface $config,
+        \Magento\CatalogInventory\Model\Stock\Status $stockStatus,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
+        array $data = array()
+    ) {
+        $this->_stockIndexerProcessor = $stockIndexerProcessor;
+        $this->_stockStatus = $stockStatus;
+        parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php
new file mode 100644
index 0000000000000000000000000000000000000000..a37250656eab99703b787dc8f9be9406e13a87c1
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Backorders.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Catalog Inventory Backorders Config Backend Model
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+namespace Magento\CatalogInventory\Model\Config\Backend;
+
+class Backorders extends AbstractValue
+{
+    /**
+     * After change Catalog Inventory Backorders value process
+     *
+     * @return $this
+     */
+    protected function _afterSave()
+    {
+        if ($this->isValueChanged() && (
+                $this->getOldValue() == \Magento\CatalogInventory\Model\Stock::BACKORDERS_NO
+                || $this->getValue() == \Magento\CatalogInventory\Model\Stock::BACKORDERS_NO
+            )
+        ) {
+            $this->_stockStatus->rebuild();
+            $this->_stockIndexerProcessor->markIndexerAsInvalid();
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
index ee210d5a1ae660856a507ac0a32ce4c2810a48cb..fb7d384834fe03c862499401e576c71b28b12f8f 100644
--- a/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/Managestock.php
@@ -30,46 +30,18 @@
  */
 namespace Magento\CatalogInventory\Model\Config\Backend;
 
-class Managestock extends \Magento\Framework\App\Config\Value
+class Managestock extends AbstractValue
 {
     /**
-     * @var \Magento\CatalogInventory\Model\Stock\Status
-     */
-    protected $_stockStatus;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $config
-     * @param \Magento\CatalogInventory\Model\Stock\Status $stockStatus
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\App\Config\ScopeConfigInterface $config,
-        \Magento\CatalogInventory\Model\Stock\Status $stockStatus,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
-    ) {
-        $this->_stockStatus = $stockStatus;
-        parent::__construct($context, $registry, $config, $resource, $resourceCollection, $data);
-    }
-
-    /**
-     * After change Catalog Inventory Manage value process
-     *
+     * After change Catalog Inventory Manage Stock value process
      * @return $this
      */
     protected function _afterSave()
     {
         if ($this->isValueChanged()) {
             $this->_stockStatus->rebuild();
+            $this->_stockIndexerProcessor->markIndexerAsInvalid();
         }
-
         return $this;
     }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Config/Backend/ShowOutOfStock.php b/app/code/Magento/CatalogInventory/Model/Config/Backend/ShowOutOfStock.php
new file mode 100644
index 0000000000000000000000000000000000000000..598ac0ca0d658988cbf7376f6adcdf5e49ec3f37
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Config/Backend/ShowOutOfStock.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+
+/**
+ * Catalog Inventory Config Backend Model
+ */
+namespace Magento\CatalogInventory\Model\Config\Backend;
+
+class ShowOutOfStock extends AbstractValue
+{
+
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
index 51d24b5e6d54e70a77dc86bf06632f05786e4e45..7a3adacfc8aa8304cc85e8318edfc1c2bb6a36f0 100644
--- a/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock.php
@@ -18,363 +18,89 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\CatalogInventory\Model\Indexer;
 
-/**
- * CatalogInventory Stock Status Indexer Model
- *
- * @method int getProductId()
- * @method \Magento\CatalogInventory\Model\Indexer\Stock setProductId(int $value)
- * @method int getWebsiteId()
- * @method \Magento\CatalogInventory\Model\Indexer\Stock setWebsiteId(int $value)
- * @method int getStockId()
- * @method \Magento\CatalogInventory\Model\Indexer\Stock setStockId(int $value)
- * @method float getQty()
- * @method \Magento\CatalogInventory\Model\Indexer\Stock setQty(float $value)
- * @method int getStockStatus()
- * @method \Magento\CatalogInventory\Model\Indexer\Stock setStockStatus(int $value)
- */
-class Stock extends \Magento\Index\Model\Indexer\AbstractIndexer
+class Stock implements \Magento\Indexer\Model\ActionInterface, \Magento\Framework\Mview\ActionInterface
 {
     /**
-     * Data key for matching result to be saved in
-     */
-    const EVENT_MATCH_RESULT_KEY = 'cataloginventory_stock_match_result';
-
-    /**
-     * @var array
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Action\Row
      */
-    protected $_matchedEntities = array(
-        \Magento\CatalogInventory\Model\Stock\Item::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Catalog\Model\Product::ENTITY => array(
-            \Magento\Index\Model\Event::TYPE_SAVE,
-            \Magento\Index\Model\Event::TYPE_MASS_ACTION,
-            \Magento\Index\Model\Event::TYPE_DELETE
-        ),
-        \Magento\Store\Model\Store::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Store\Model\Group::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE),
-        \Magento\Framework\App\Config\ValueInterface::ENTITY => array(\Magento\Index\Model\Event::TYPE_SAVE)
-    );
+    protected $_productStockIndexerRow;
 
     /**
-     * Related config settings
-     *
-     * @var string[]
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows
      */
-    protected $_relatedConfigSettings = array(
-        \Magento\CatalogInventory\Model\Stock\Item::XML_PATH_MANAGE_STOCK,
-        \Magento\CatalogInventory\Helper\Data::XML_PATH_SHOW_OUT_OF_STOCK
-    );
+    protected $_productStockIndexerRows;
 
     /**
-     * Catalog inventory data
-     *
-     * @var \Magento\CatalogInventory\Helper\Data
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Action\Full
      */
-    protected $_catalogInventoryData;
+    protected $_productStockIndexerFull;
 
     /**
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
-    /**
-     * @param \Magento\Framework\Model\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Index\Model\Indexer $indexer
-     * @param \Magento\CatalogInventory\Helper\Data $catalogInventoryData
-     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
-     * @param \Magento\Framework\Data\Collection\Db $resourceCollection
-     * @param array $data
+     * @param Stock\Action\Row $productStockIndexerRow
+     * @param Stock\Action\Rows $productStockIndexerRows
+     * @param Stock\Action\Full $productStockIndexerFull
      */
     public function __construct(
-        \Magento\Framework\Model\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Index\Model\Indexer $indexer,
-        \Magento\CatalogInventory\Helper\Data $catalogInventoryData,
-        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
-        \Magento\Framework\Data\Collection\Db $resourceCollection = null,
-        array $data = array()
+        \Magento\CatalogInventory\Model\Indexer\Stock\Action\Row $productStockIndexerRow,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows $productStockIndexerRows,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Action\Full $productStockIndexerFull
     ) {
-        parent::__construct($context, $registry, $resource, $resourceCollection, $data);
-
-        $this->_indexer = $indexer;
-        $this->_catalogInventoryData = $catalogInventoryData;
-    }
-
-    /**
-     * Initialize resource model
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('Magento\CatalogInventory\Model\Resource\Indexer\Stock');
-    }
-
-    /**
-     * Retrieve resource instance wrapper
-     *
-     * @return \Magento\CatalogInventory\Model\Resource\Indexer\Stock
-     */
-    protected function _getResource()
-    {
-        return parent::_getResource();
-    }
-
-    /**
-     * Retrieve Indexer name
-     *
-     * @return string
-     */
-    public function getName()
-    {
-        return __('Stock Status');
-    }
-
-    /**
-     * Retrieve Indexer description
-     *
-     * @return string
-     */
-    public function getDescription()
-    {
-        return __('Index Product Stock Status');
+        $this->_productStockIndexerRow = $productStockIndexerRow;
+        $this->_productStockIndexerRows = $productStockIndexerRows;
+        $this->_productStockIndexerFull = $productStockIndexerFull;
     }
 
     /**
-     * Check if event can be matched by process.
-     * Overwrote for specific config save, store and store groups save matching
+     * Execute materialization on ids entities
      *
-     * @param \Magento\Index\Model\Event $event
-     * @return bool
-     */
-    public function matchEvent(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
-            return $data[self::EVENT_MATCH_RESULT_KEY];
-        }
-
-        $entity = $event->getEntity();
-        if ($entity == \Magento\Store\Model\Store::ENTITY) {
-            /* @var $store \Magento\Store\Model\Store */
-            $store = $event->getDataObject();
-            if ($store && $store->isObjectNew()) {
-                $result = true;
-            } else {
-                $result = false;
-            }
-        } else {
-            if ($entity == \Magento\Store\Model\Group::ENTITY) {
-                /* @var $storeGroup \Magento\Store\Model\Group */
-                $storeGroup = $event->getDataObject();
-                if ($storeGroup && $storeGroup->dataHasChangedFor('website_id')) {
-                    $result = true;
-                } else {
-                    $result = false;
-                }
-            } else {
-                if ($entity == \Magento\Framework\App\Config\ValueInterface::ENTITY) {
-                    $configData = $event->getDataObject();
-                    if ($configData && in_array($configData->getPath(), $this->_relatedConfigSettings)) {
-                        $result = $configData->isValueChanged();
-                    } else {
-                        $result = false;
-                    }
-                } else {
-                    $result = parent::matchEvent($event);
-                }
-            }
-        }
-
-        $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
-
-        return $result;
-    }
-
-    /**
-     * Register data required by process in event object
+     * @param int[] $ids
      *
-     * @param \Magento\Index\Model\Event $event
      * @return void
      */
-    protected function _registerEvent(\Magento\Index\Model\Event $event)
+    public function execute($ids)
     {
-        $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
-        switch ($event->getEntity()) {
-            case \Magento\CatalogInventory\Model\Stock\Item::ENTITY:
-                $this->_registerCatalogInventoryStockItemEvent($event);
-                break;
-            case \Magento\Catalog\Model\Product::ENTITY:
-                $this->_registerCatalogProductEvent($event);
-                break;
-            case \Magento\Store\Model\Store::ENTITY:
-            case \Magento\Store\Model\Group::ENTITY:
-            case \Magento\Framework\App\Config\ValueInterface::ENTITY:
-                $event->addNewData('cataloginventory_stock_skip_call_event_handler', true);
-                $process = $event->getProcess();
-                $process->changeStatus(\Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX);
-
-                if ($event->getEntity() == \Magento\Framework\App\Config\ValueInterface::ENTITY) {
-                    $configData = $event->getDataObject();
-                    if ($configData->getPath() == \Magento\CatalogInventory\Helper\Data::XML_PATH_SHOW_OUT_OF_STOCK) {
-                        $this->_indexer->getProcessByCode('catalog_product_attribute')
-                            ->changeStatus(\Magento\Index\Model\Process::STATUS_REQUIRE_REINDEX);
-                    }
-                }
-                break;
-            default:
-                break;
-        }
+        $this->_productStockIndexerRows->execute($ids);
     }
 
     /**
-     * Register data required by catalog product processes in event object
+     * Execute full indexation
      *
-     * @param \Magento\Index\Model\Event $event
      * @return void
      */
-    protected function _registerCatalogProductEvent(\Magento\Index\Model\Event $event)
+    public function executeFull()
     {
-        switch ($event->getType()) {
-            case \Magento\Index\Model\Event::TYPE_SAVE:
-                $product = $event->getDataObject();
-                if ($product && $product->getStockData()) {
-                    $product->setForceReindexRequired(true);
-                }
-                break;
-            case \Magento\Index\Model\Event::TYPE_MASS_ACTION:
-                $this->_registerCatalogProductMassActionEvent($event);
-                break;
-            case \Magento\Index\Model\Event::TYPE_DELETE:
-                $this->_registerCatalogProductDeleteEvent($event);
-                break;
-            default:
-                break;
-        }
+        $this->_productStockIndexerFull->execute();
     }
 
     /**
-     * Register data required by cataloginventory stock item processes in event object
+     * Execute partial indexation by ID list
      *
-     * @param \Magento\Index\Model\Event $event
-     * @return void
-     */
-    protected function _registerCatalogInventoryStockItemEvent(\Magento\Index\Model\Event $event)
-    {
-        switch ($event->getType()) {
-            case \Magento\Index\Model\Event::TYPE_SAVE:
-                $this->_registerStockItemSaveEvent($event);
-                break;
-            default:
-                break;
-        }
-    }
-
-    /**
-     * Register data required by stock item save process in event object
+     * @param int[] $ids
      *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerStockItemSaveEvent(\Magento\Index\Model\Event $event)
-    {
-        /* @var $object \Magento\CatalogInventory\Model\Stock\Item */
-        $object = $event->getDataObject();
-
-        $event->addNewData('reindex_stock', 1);
-        $event->addNewData('product_id', $object->getProductId());
-
-        // Saving stock item without product object
-        // Register re-index price process if products out of stock hidden on Front-end
-        if (!$this->_catalogInventoryData->isShowOutOfStock() /**&& !$object->getProduct() */) {
-            $massObject = new \Magento\Framework\Object();
-            $massObject->setAttributesData(array('force_reindex_required' => 1));
-            $massObject->setProductIds(array($object->getProductId()));
-            $this->_indexer->logEvent(
-                $massObject,
-                \Magento\Catalog\Model\Product::ENTITY,
-                \Magento\Index\Model\Event::TYPE_MASS_ACTION
-            );
-        }
-
-        return $this;
-    }
-
-    /**
-     * Register data required by product delete process in event object
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
+     * @return void
      */
-    protected function _registerCatalogProductDeleteEvent(\Magento\Index\Model\Event $event)
+    public function executeList($ids)
     {
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $event->getDataObject();
-
-        $parentIds = $this->_getResource()->getProductParentsByChild($product->getId());
-        if ($parentIds) {
-            $event->addNewData('reindex_stock_parent_ids', $parentIds);
-        }
-
-        return $this;
+        $this->_productStockIndexerRows->execute($ids);
     }
 
     /**
-     * Register data required by product mass action process in event object
+     * Execute partial indexation by ID
      *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    protected function _registerCatalogProductMassActionEvent(\Magento\Index\Model\Event $event)
-    {
-        /* @var $actionObject \Magento\Framework\Object */
-        $actionObject = $event->getDataObject();
-        $attributes = array('status');
-        $reindexStock = false;
-
-        // check if attributes changed
-        $attrData = $actionObject->getAttributesData();
-        if (is_array($attrData)) {
-            foreach ($attributes as $attributeCode) {
-                if (array_key_exists($attributeCode, $attrData)) {
-                    $reindexStock = true;
-                    break;
-                }
-            }
-        }
-
-        // check changed websites
-        if ($actionObject->getWebsiteIds()) {
-            $reindexStock = true;
-        }
-
-        // register affected products
-        if ($reindexStock) {
-            $event->addNewData('reindex_stock_product_ids', $actionObject->getProductIds());
-        }
-
-        return $this;
-    }
-
-    /**
-     * Process event
+     * @param int $id
      *
-     * @param \Magento\Index\Model\Event $event
      * @return void
      */
-    protected function _processEvent(\Magento\Index\Model\Event $event)
+    public function executeRow($id)
     {
-        $data = $event->getNewData();
-        if (!empty($data['cataloginventory_stock_reindex_all'])) {
-            $this->reindexAll();
-        }
-        if (empty($data['cataloginventory_stock_skip_call_event_handler'])) {
-            $this->callEventHandler($event);
-        }
+        $this->_productStockIndexerRow->execute($id);
     }
 }
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..262efba6c7effddf8cb05a7d47836c64144fa784
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/AbstractAction.php
@@ -0,0 +1,288 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock;
+
+/**
+ * Abstract action reindex class
+ *
+ * @package Magento\CatalogInventory\Model\Indexer\Stock
+ */
+abstract class AbstractAction
+{
+    /**
+     * Resource instance
+     *
+     * @var \Magento\Framework\App\Resource
+     */
+    protected $_resource;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Resource\Indexer\StockFactory
+     */
+    protected $_indexerFactory;
+
+    /**
+     * @var \Magento\Catalog\Model\Product\Type
+     */
+    protected $_catalogProductType;
+
+    /**
+     * @var \Magento\Framework\DB\Adapter\AdapterInterface
+     */
+    protected $_connection;
+
+    /**
+     * Stock Indexer models per product type
+     * Sorted by priority
+     *
+     * @var array
+     */
+    protected $_indexers = array();
+
+    /**
+     * Flag that defines if need to use "_idx" index table suffix instead of "_tmp"
+     *
+     * @var bool
+     */
+    protected $_isNeedUseIdxTable = false;
+
+    /**
+     * @param \Magento\Framework\App\Resource $resource
+     * @param \Magento\CatalogInventory\Model\Resource\Indexer\StockFactory $indexerFactory
+     * @param \Magento\Catalog\Model\Product\Type $catalogProductType
+     */
+    public function __construct(
+        \Magento\Framework\App\Resource $resource,
+        \Magento\CatalogInventory\Model\Resource\Indexer\StockFactory $indexerFactory,
+        \Magento\Catalog\Model\Product\Type $catalogProductType
+    ) {
+        $this->_resource = $resource;
+        $this->_indexerFactory = $indexerFactory;
+        $this->_catalogProductType = $catalogProductType;
+    }
+
+    /**
+     * Execute action for given ids
+     *
+     * @param array|int $ids
+     *
+     * @return void
+     */
+    abstract public function execute($ids);
+
+    /**
+     * Retrieve connection instance
+     *
+     * @return bool|\Magento\Framework\DB\Adapter\AdapterInterface
+     */
+    protected function _getConnection()
+    {
+        if (null === $this->_connection) {
+            $this->_connection = $this->_resource->getConnection('write');
+        }
+        return $this->_connection;
+    }
+
+    /**
+     * Retrieve Stock Indexer Models per Product Type
+     *
+     * @return \Magento\CatalogInventory\Model\Resource\Indexer\Stock\StockInterface[]
+     */
+    protected function _getTypeIndexers()
+    {
+        if (empty($this->_indexers)) {
+            foreach ($this->_catalogProductType->getTypesByPriority() as $typeId => $typeInfo) {
+                $indexerClassName = isset($typeInfo['stock_indexer']) ? $typeInfo['stock_indexer'] : '';
+
+                $indexer = $this->_indexerFactory->create($indexerClassName)
+                    ->setTypeId($typeId)
+                    ->setIsComposite(!empty($typeInfo['composite']));
+
+                $this->_indexers[$typeId] = $indexer;
+            }
+        }
+        return $this->_indexers;
+    }
+
+    /**
+     * Returns table name for given entity
+     *
+     * @param string $entityName
+     * @return string
+     */
+    protected function _getTable($entityName)
+    {
+        return $this->_resource->getTableName($entityName);
+    }
+
+    /**
+     * Retrieve product relations by children
+     *
+     * @param int|array $childIds
+     * @return array
+     */
+    public function getRelationsByChild($childIds)
+    {
+        $adapter = $this->_getConnection();
+        $select = $adapter->select()
+            ->from($this->_getTable('catalog_product_relation'), 'parent_id')
+            ->where('child_id IN(?)', $childIds);
+
+        return $adapter->fetchCol($select);
+    }
+
+    /**
+     * Reindex all
+     *
+     * @return void
+     */
+    public function reindexAll()
+    {
+        $this->useIdxTable(true);
+        $this->clearTemporaryIndexTable();
+
+        foreach ($this->_getTypeIndexers() as $indexer) {
+            $indexer->reindexAll();
+        }
+
+        $this->_syncData();
+    }
+
+    /**
+     * Synchronize data between index storage and original storage
+     *
+     * @return $this
+     */
+    protected function _syncData()
+    {
+        $idxTableName = $this->_getIdxTable();
+        $tableName = $this->_getTable('cataloginventory_stock_status');
+
+        $this->_deleteOldRelations($tableName);
+
+        $columns = array_keys($this->_connection->describeTable($idxTableName));
+        $select = $this->_connection->select()->from($idxTableName, $columns);
+        $query = $select->insertFromSelect($tableName, $columns);
+        $this->_connection->query($query);
+        return $this;
+    }
+
+    /**
+     * Delete old relations
+     *
+     * @param string $tableName
+     *
+     * @return void
+     */
+    protected function _deleteOldRelations($tableName)
+    {
+        $select = $this->_connection->select()
+            ->from(array('s' => $tableName))
+            ->joinLeft(
+                array('w' => $this->_getTable('catalog_product_website')),
+                's.product_id = w.product_id AND s.website_id = w.website_id',
+                array()
+            )
+            ->where('w.product_id IS NULL');
+
+        $sql = $select->deleteFromSelect('s');
+        $this->_connection->query($sql);
+    }
+
+    /**
+     * Refresh entities index
+     *
+     * @param array $productIds
+     * @return array Affected ids
+     */
+    protected function _reindexRows($productIds = array())
+    {
+        $adapter = $this->_getConnection();
+        if (!is_array($productIds)) {
+            $productIds = array($productIds);
+        }
+        $parentIds = $this->getRelationsByChild($productIds);
+        $processIds = $parentIds ? array_merge($parentIds, $productIds) : $productIds;
+
+        // retrieve product types by processIds
+        $select = $adapter->select()
+            ->from($this->_getTable('catalog_product_entity'), array('entity_id', 'type_id'))
+            ->where('entity_id IN(?)', $processIds);
+        $pairs = $adapter->fetchPairs($select);
+
+        $byType = array();
+        foreach ($pairs as $productId => $typeId) {
+            $byType[$typeId][$productId] = $productId;
+        }
+
+        $indexers = $this->_getTypeIndexers();
+        foreach ($indexers as $indexer) {
+            if (isset($byType[$indexer->getTypeId()])) {
+                $indexer->reindexEntity($byType[$indexer->getTypeId()]);
+            }
+        }
+
+        return $this;
+    }
+
+    /**
+     * Set or get what either "_idx" or "_tmp" suffixed temporary index table need to use
+     *
+     * @param bool|null $value
+     * @return bool
+     */
+    public function useIdxTable($value = null)
+    {
+        if (!is_null($value)) {
+            $this->_isNeedUseIdxTable = (bool)$value;
+        }
+        return $this->_isNeedUseIdxTable;
+    }
+
+    /**
+     * Retrieve temporary index table name
+     *
+     * @return string
+     */
+    protected function _getIdxTable()
+    {
+        if ($this->useIdxTable()) {
+            return $this->_getTable('cataloginventory_stock_status_idx');
+        }
+        return $this->_getTable('cataloginventory_stock_status_tmp');
+    }
+
+    /**
+     * Clean up temporary index table
+     *
+     * @return void
+     */
+    public function clearTemporaryIndexTable()
+    {
+        $this->_getConnection()->delete($this->_getIdxTable());
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d88db89b6930d4620d214608b2a9d2e7116e3b6
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Full.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Class Full reindex action
+ *
+ * @package Magento\CatalogInventory\Model\Indexer\Stock\Action
+ */
+class Full extends \Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction
+{
+    /**
+     * Execute Full reindex
+     *
+     * @param null|array $ids
+     * @throws \Magento\CatalogInventory\Exception
+     *
+     * @return void
+     */
+    public function execute($ids = null)
+    {
+        try {
+            $this->reindexAll();
+        } catch (\Exception $e) {
+            throw new \Magento\CatalogInventory\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Row.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Row.php
new file mode 100644
index 0000000000000000000000000000000000000000..91c0894d30288e9ffa5757c254834e6a3751ba2d
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Row.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Class Row reindex action
+ *
+ * @package Magento\CatalogInventory\Model\Indexer\Stock\Action
+ */
+class Row extends \Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction
+{
+    /**
+     * Execute Row reindex
+     *
+     * @param int|null $id
+     * @throws \Magento\CatalogInventory\Exception
+     *
+     * @return void
+     */
+    public function execute($id = null)
+    {
+        if (!isset($id) || empty($id)) {
+            throw new \Magento\CatalogInventory\Exception(__('Could not rebuild index for undefined product'));
+        }
+        try {
+            $this->_reindexRows(array($id));
+        } catch (\Exception $e) {
+            throw new \Magento\CatalogInventory\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Rows.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Rows.php
new file mode 100644
index 0000000000000000000000000000000000000000..e238d2367e58b63a827cc7c5a89a38359023cd87
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Action/Rows.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Class Rows reindex action for mass actions
+ *
+ * @package Magento\CatalogInventory\Model\Indexer\Stock\Action
+ */
+class Rows extends \Magento\CatalogInventory\Model\Indexer\Stock\AbstractAction
+{
+    /**
+     * Execute Rows reindex
+     *
+     * @param array $ids
+     * @throws \Magento\CatalogInventory\Exception
+     *
+     * @return void
+     */
+    public function execute($ids)
+    {
+        if (empty($ids)) {
+            throw new \Magento\CatalogInventory\Exception(__('Could not rebuild index for empty products array'));
+        }
+        try {
+            $this->_reindexRows($ids);
+        } catch (\Exception $e) {
+            throw new \Magento\CatalogInventory\Exception($e->getMessage(), $e->getCode(), $e);
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroup.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..e15bab19dbbd0870d9f6bf6aebe457084cad3d8f
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroup.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Plugin;
+
+class StoreGroup
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_indexerProcessor;
+
+    /**
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor  $indexerProcessor
+     */
+    public function __construct(\Magento\CatalogInventory\Model\Indexer\Stock\Processor $indexerProcessor)
+    {
+        $this->_indexerProcessor = $indexerProcessor;
+    }
+
+    /**
+     * Before save handler
+     *
+     * @param \Magento\Store\Model\Resource\Group $subject
+     * @param \Magento\Framework\Model\AbstractModel $object
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeSave(
+        \Magento\Store\Model\Resource\Group $subject,
+        \Magento\Framework\Model\AbstractModel $object
+    ) {
+        if (!$object->getId() || $object->dataHasChangedFor('website_id')) {
+            $this->_indexerProcessor->markIndexerAsInvalid();
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Processor.php b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Processor.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f57ceab1b5c63a6f73a78d4e107f92cde19c955
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/Model/Indexer/Stock/Processor.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock;
+
+class Processor extends \Magento\Indexer\Model\Indexer\AbstractProcessor
+{
+    /**
+     * Indexer ID
+     */
+    const INDEXER_ID = 'cataloginventory_stock';
+}
diff --git a/app/code/Magento/CatalogInventory/Model/Observer.php b/app/code/Magento/CatalogInventory/Model/Observer.php
index 62f5455a63395a8c8705df344ae48823a144c5ae..b178d8a56278625ac777ea20292e57f27b128a4f 100644
--- a/app/code/Magento/CatalogInventory/Model/Observer.php
+++ b/app/code/Magento/CatalogInventory/Model/Observer.php
@@ -74,13 +74,6 @@ class Observer
      */
     protected $_stockStatusFactory;
 
-    /**
-     * Construct
-     *
-     * @var \Magento\Index\Model\Indexer
-     */
-    protected $_indexer;
-
     /**
      * @var Stock
      */
@@ -97,9 +90,9 @@ class Observer
     protected $_resourceStock;
 
     /**
-     * @var \Magento\CatalogInventory\Model\Resource\Indexer\Stock
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
      */
-    protected $_resourceIndexerStock;
+    protected $_stockIndexerProcessor;
 
     /**
      * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface
@@ -162,9 +155,8 @@ class Observer
 
     /**
      * @param \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer
-     * @param Resource\Indexer\Stock $resourceIndexerStock
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor
      * @param Resource\Stock $resourceStock
-     * @param \Magento\Index\Model\Indexer $indexer
      * @param Stock $stock
      * @param Stock\Status $stockStatus
      * @param \Magento\CatalogInventory\Helper\Data $catalogInventoryData
@@ -176,9 +168,8 @@ class Observer
      */
     public function __construct(
         \Magento\Catalog\Model\Indexer\Product\Price\Processor $priceIndexer,
-        \Magento\CatalogInventory\Model\Resource\Indexer\Stock $resourceIndexerStock,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor,
         \Magento\CatalogInventory\Model\Resource\Stock $resourceStock,
-        \Magento\Index\Model\Indexer $indexer,
         Stock $stock,
         \Magento\CatalogInventory\Model\Stock\Status $stockStatus,
         \Magento\CatalogInventory\Helper\Data $catalogInventoryData,
@@ -189,9 +180,8 @@ class Observer
         \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry
     ) {
         $this->_priceIndexer = $priceIndexer;
-        $this->_resourceIndexerStock = $resourceIndexerStock;
+        $this->_stockIndexerProcessor = $stockIndexerProcessor;
         $this->_resourceStock = $resourceStock;
-        $this->_indexer = $indexer;
         $this->_stock = $stock;
         $this->_stockStatus = $stockStatus;
         $this->_catalogInventoryData = $catalogInventoryData;
@@ -360,7 +350,11 @@ class Observer
         $quote = $observer->getEvent()->getQuote();
         $items = $this->_getProductsQty($quote->getAllItems());
         $this->_stock->revertProductsSale($items);
-
+        $productIds = array_keys($items);
+        if (!empty($productIds)) {
+            $this->_stockIndexerProcessor->reindexList($productIds);
+            $this->_priceIndexer->reindexList($productIds);
+        }
         // Clear flag, so if order placement retried again with success - it will be processed
         $quote->setInventoryProcessed(false);
     }
@@ -451,7 +445,7 @@ class Observer
         }
 
         if (count($productIds)) {
-            $this->_resourceIndexerStock->reindexProducts($productIds);
+            $this->_stockIndexerProcessor->reindexList($productIds);
         }
 
         // Reindex previously remembered items
@@ -481,30 +475,30 @@ class Observer
     {
         /* @var $creditmemo \Magento\Sales\Model\Order\Creditmemo */
         $creditmemo = $observer->getEvent()->getCreditmemo();
-        $items = array();
+        $itemsToUpdate = [];
         foreach ($creditmemo->getAllItems() as $item) {
-            /* @var $item \Magento\Sales\Model\Order\Creditmemo\Item */
-            $return = false;
-            if ($item->hasBackToStock()) {
-                if ($item->getBackToStock() && $item->getQty()) {
-                    $return = true;
-                }
-            } elseif ($this->_catalogInventoryData->isAutoReturnEnabled()) {
-                $return = true;
-            }
-            if ($return) {
-                $parentOrderId = $item->getOrderItem()->getParentItemId();
+            $qty = $item->getQty();
+            if (($item->getBackToStock() && $qty) || $this->_catalogInventoryData->isAutoReturnEnabled()) {
+                $productId = $item->getProductId();
+                $parentItemId = $item->getOrderItem()->getParentItemId();
                 /* @var $parentItem \Magento\Sales\Model\Order\Creditmemo\Item */
-                $parentItem = $parentOrderId ? $creditmemo->getItemByOrderId($parentOrderId) : false;
-                $qty = $parentItem ? $parentItem->getQty() * $item->getQty() : $item->getQty();
-                if (isset($items[$item->getProductId()])) {
-                    $items[$item->getProductId()]['qty'] += $qty;
+                $parentItem = $parentItemId ? $creditmemo->getItemByOrderId($parentItemId) : false;
+                $qty = $parentItem ? $parentItem->getQty() * $qty : $qty;
+                if (isset($itemsToUpdate[$productId]['qty'])) {
+                    $itemsToUpdate[$productId]['qty'] += $qty;
                 } else {
-                    $items[$item->getProductId()] = array('qty' => $qty, 'item' => null);
+                    $itemsToUpdate[$productId] = ['qty' => $qty, 'item' => null];
                 }
             }
         }
-        $this->_stock->revertProductsSale($items);
+
+        if (!empty($itemsToUpdate)) {
+            $this->_stock->revertProductsSale($itemsToUpdate);
+
+            $updatedItemIds = array_keys($itemsToUpdate);
+            $this->_stockIndexerProcessor->reindexList($updatedItemIds);
+            $this->_priceIndexer->reindexList($updatedItemIds);
+        }
     }
 
     /**
@@ -523,7 +517,7 @@ class Observer
         if ($item->getId() && $item->getProductId() && empty($children) && $qty) {
             $this->_stock->backItemQty($item->getProductId(), $qty);
         }
-
+        $this->_priceIndexer->reindexRow($item->getProductId());
         return $this;
     }
 
@@ -606,19 +600,6 @@ class Observer
         return $this;
     }
 
-    /**
-     * Reindex all events of product-massAction type
-     *
-     * @return void
-     */
-    public function reindexProductsMassAction()
-    {
-        $this->_indexer->indexEvents(
-            \Magento\Catalog\Model\Product::ENTITY,
-            \Magento\Index\Model\Event::TYPE_MASS_ACTION
-        );
-    }
-
     /**
      * Detects whether product status should be shown
      *
diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Indexer/Stock.php b/app/code/Magento/CatalogInventory/Model/Resource/Indexer/Stock.php
deleted file mode 100644
index 4b1659ee7ef4798259a02e96dca79cff3a92d345..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogInventory/Model/Resource/Indexer/Stock.php
+++ /dev/null
@@ -1,340 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\CatalogInventory\Model\Resource\Indexer;
-
-/**
- * CatalogInventory Stock Status Indexer Resource Model
- */
-class Stock extends \Magento\Catalog\Model\Resource\Product\Indexer\AbstractIndexer
-{
-    /**
-     * Stock Indexer models per product type
-     * Sorted by priority
-     *
-     * @var array
-     */
-    protected $_indexers = array();
-
-    /**
-     * @var StockFactory
-     */
-    protected $_indexerFactory;
-
-    /**
-     * @var \Magento\Catalog\Model\Product\Type
-     */
-    protected $_productType;
-
-    /**
-     * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Eav\Model\Config $eavConfig
-     * @param StockFactory $indexerFactory
-     * @param \Magento\Catalog\Model\Product\Type $productType
-     */
-    public function __construct(
-        \Magento\Framework\App\Resource $resource,
-        \Magento\Eav\Model\Config $eavConfig,
-        StockFactory $indexerFactory,
-        \Magento\Catalog\Model\Product\Type $productType
-    ) {
-        $this->_indexerFactory = $indexerFactory;
-        $this->_productType = $productType;
-        parent::__construct($resource, $eavConfig);
-    }
-
-    /**
-     * Initialize connection and define main table
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_init('cataloginventory_stock_status', 'product_id');
-    }
-
-    /**
-     * Process stock item save action
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @return $this
-     */
-    public function cataloginventoryStockItemSave(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['product_id'])) {
-            return $this;
-        }
-
-        $productId = $data['product_id'];
-        $this->reindexProducts($productId);
-
-        return $this;
-    }
-
-    /**
-     * Refresh stock index for specific product ids
-     *
-     * @param int|array $productIds
-     * @throws \Exception
-     * @return $this
-     */
-    public function reindexProducts($productIds)
-    {
-        $adapter = $this->_getWriteAdapter();
-        if (!is_array($productIds)) {
-            $productIds = array($productIds);
-        }
-        $parentIds = $this->getRelationsByChild($productIds);
-        if ($parentIds) {
-            $processIds = array_merge($parentIds, $productIds);
-        } else {
-            $processIds = $productIds;
-        }
-
-        // retrieve product types by processIds
-        $select = $adapter->select()->from($this->getTable('catalog_product_entity'), array('entity_id', 'type_id'))
-            ->where('entity_id IN(?)', $processIds);
-        $pairs = $adapter->fetchPairs($select);
-
-        $byType = array();
-        foreach ($pairs as $productId => $typeId) {
-            $byType[$typeId][$productId] = $productId;
-        }
-
-        $adapter->beginTransaction();
-        try {
-            $indexers = $this->_getTypeIndexers();
-            foreach ($indexers as $indexer) {
-                if (isset($byType[$indexer->getTypeId()])) {
-                    $indexer->reindexEntity($byType[$indexer->getTypeId()]);
-                }
-            }
-        } catch (\Exception $e) {
-            $adapter->rollback();
-            throw $e;
-        }
-        $adapter->commit();
-
-        return $this;
-    }
-
-    /**
-     * Processing parent products after child product deleted
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @throws \Exception
-     * @return $this
-     */
-    public function catalogProductDelete(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['reindex_stock_parent_ids'])) {
-            return $this;
-        }
-
-        $adapter = $this->_getWriteAdapter();
-
-        $parentIds = array();
-        foreach ($data['reindex_stock_parent_ids'] as $parentId => $parentType) {
-            $parentIds[$parentType][$parentId] = $parentId;
-        }
-
-        $adapter->beginTransaction();
-        try {
-            foreach ($parentIds as $parentType => $entityIds) {
-                $this->_getIndexer($parentType)->reindexEntity($entityIds);
-            }
-        } catch (\Exception $e) {
-            $adapter->rollback();
-            throw $e;
-        }
-
-        $adapter->commit();
-
-        return $this;
-    }
-
-    /**
-     * Process product mass update action
-     *
-     * @param \Magento\Index\Model\Event $event
-     * @throws \Exception
-     * @return $this
-     */
-    public function catalogProductMassAction(\Magento\Index\Model\Event $event)
-    {
-        $data = $event->getNewData();
-        if (empty($data['reindex_stock_product_ids'])) {
-            return $this;
-        }
-
-        $adapter = $this->_getWriteAdapter();
-        $processIds = $data['reindex_stock_product_ids'];
-        $select = $adapter->select()->from($this->getTable('catalog_product_entity'), 'COUNT(*)');
-        $pCount = $adapter->fetchOne($select);
-
-        // if affected more 30% of all products - run reindex all products
-        if ($pCount * 0.3 < count($processIds)) {
-            return $this->reindexAll();
-        }
-
-        // calculate relations
-        $select = $adapter->select()->from($this->getTable('catalog_product_relation'), 'COUNT(DISTINCT parent_id)')
-            ->where('child_id IN(?)', $processIds);
-        $aCount = $adapter->fetchOne($select);
-        $select = $adapter->select()->from($this->getTable('catalog_product_relation'), 'COUNT(DISTINCT child_id)')
-            ->where('parent_id IN(?)', $processIds);
-        $bCount = $adapter->fetchOne($select);
-
-        // if affected with relations more 30% of all products - run reindex all products
-        if ($pCount * 0.3 < count($processIds) + $aCount + $bCount) {
-            return $this->reindexAll();
-        }
-
-
-        // retrieve affected parent relation products
-        $parentIds = $this->getRelationsByChild($processIds);
-        if ($parentIds) {
-            $processIds = array_merge($processIds, $parentIds);
-        }
-
-        // retrieve products types
-        $select = $adapter->select()->from($this->getTable('catalog_product_entity'), array('entity_id', 'type_id'))
-            ->where('entity_id IN(?)', $processIds);
-        $query = $select->query(\Zend_Db::FETCH_ASSOC);
-        $byType = array();
-        while ($row = $query->fetch()) {
-            $byType[$row['type_id']][] = $row['entity_id'];
-        }
-
-        $adapter->beginTransaction();
-        try {
-            $indexers = $this->_getTypeIndexers();
-            foreach ($indexers as $indexer) {
-                if (!empty($byType[$indexer->getTypeId()])) {
-                    $indexer->reindexEntity($byType[$indexer->getTypeId()]);
-                }
-            }
-        } catch (\Exception $e) {
-            $adapter->rollback();
-            throw $e;
-        }
-        $adapter->commit();
-
-        return $this;
-    }
-
-    /**
-     * Rebuild all index data
-     *
-     * @throws \Exception
-     * @return $this
-     */
-    public function reindexAll()
-    {
-        $this->useIdxTable(true);
-        $this->beginTransaction();
-        try {
-            $this->clearTemporaryIndexTable();
-
-            foreach ($this->_getTypeIndexers() as $indexer) {
-                $indexer->reindexAll();
-            }
-
-            $this->syncData();
-            $this->commit();
-        } catch (\Exception $e) {
-            $this->rollBack();
-            throw $e;
-        }
-        return $this;
-    }
-
-    /**
-     * Retrieve Stock Indexer Models per Product Type
-     *
-     * @return array
-     */
-    protected function _getTypeIndexers()
-    {
-        if (empty($this->_indexers)) {
-            foreach ($this->_productType->getTypesByPriority() as $typeId => $typeInfo) {
-                $indexerClassName = isset($typeInfo['stock_indexer']) ? $typeInfo['stock_indexer'] : '';
-
-                $indexer = $this->_indexerFactory->create($indexerClassName)
-                    ->setTypeId($typeId)
-                    ->setIsComposite(!empty($typeInfo['composite']));
-                $this->_indexers[$typeId] = $indexer;
-            }
-        }
-        return $this->_indexers;
-    }
-
-    /**
-     * Retrieve Stock indexer by Product Type
-     *
-     * @param string $productTypeId
-     * @return \Magento\CatalogInventory\Model\Resource\Indexer\Stock\StockInterface
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function _getIndexer($productTypeId)
-    {
-        $types = $this->_getTypeIndexers();
-        if (!isset($types[$productTypeId])) {
-            throw new \Magento\Framework\Model\Exception(__('Unsupported product type "%1".', $productTypeId));
-        }
-        return $types[$productTypeId];
-    }
-
-    /**
-     * Retrieve parent ids and types by child id
-     * Return array with key product_id and value as product type id
-     *
-     * @param int $childId
-     * @return array
-     */
-    public function getProductParentsByChild($childId)
-    {
-        $write = $this->_getWriteAdapter();
-        $select = $write->select()->from(['l' => $this->getTable('catalog_product_relation')], ['parent_id'])
-            ->join(['e' => $this->getTable('catalog_product_entity')], 'l.parent_id=e.entity_id', ['e.type_id'])
-            ->where('l.child_id = :child_id');
-        return $write->fetchPairs($select, array(':child_id' => $childId));
-    }
-
-    /**
-     * Retrieve temporary index table name
-     *
-     * @param string $table
-     * @return string
-     */
-    public function getIdxTable($table = null)
-    {
-        if ($this->useIdxTable()) {
-            return $this->getTable('cataloginventory_stock_status_idx');
-        }
-        return $this->getTable('cataloginventory_stock_status_tmp');
-    }
-}
diff --git a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php
index 63e7109d8d1379ec65958196ff646613daa5ffb6..0e77c339bfc69937edb58edb6fb06fac99f5c5f6 100644
--- a/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php
+++ b/app/code/Magento/CatalogInventory/Model/Resource/Stock/Status.php
@@ -305,11 +305,10 @@ class Status extends \Magento\Framework\Model\Resource\Db\AbstractDb
         } else {
             $select = $adapter->select()->from(
                 array('t1' => $attributeTable),
-                array('value' => $adapter->getCheckSql('t2.value_id > 0', 't2.value', 't1.value'))
+                array('entity_id' => 't1.entity_id', 'value' => $adapter->getIfNullSql('t2.value', 't1.value'))
             )->joinLeft(
                 array('t2' => $attributeTable),
-                't1.entity_id = t2.entity_id AND t1.attribute_id = t2.attribute_id AND t2.store_id = ' . (int)$storeId,
-                array('t1.entity_id')
+                't1.entity_id = t2.entity_id AND t1.attribute_id = t2.attribute_id AND t2.store_id = ' . (int)$storeId
             )->where(
                 't1.store_id = ?',
                 \Magento\Store\Model\Store::DEFAULT_STORE_ID
diff --git a/app/code/Magento/CatalogInventory/Model/Stock/Item.php b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
index 772335e07bdf6808f17ef70212052c278381a1a3..0f0560ec06a5689f9c77b1a0a799a9b249a37b03 100644
--- a/app/code/Magento/CatalogInventory/Model/Stock/Item.php
+++ b/app/code/Magento/CatalogInventory/Model/Stock/Item.php
@@ -218,9 +218,9 @@ class Item extends \Magento\Framework\Model\AbstractModel
     protected $_stockStatus;
 
     /**
-     * @var \Magento\Index\Model\Indexer
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
      */
-    protected $_indexer;
+    protected $_stockIndexerProcessor;
 
     /**
      * @var \Magento\Customer\Model\Session
@@ -246,7 +246,7 @@ class Item extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Index\Model\Indexer $indexer
+     * @param \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor
      * @param Status $stockStatus
      * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService
      * @param ItemRegistry $stockItemRegistry
@@ -265,7 +265,7 @@ class Item extends \Magento\Framework\Model\AbstractModel
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Customer\Model\Session $customerSession,
-        \Magento\Index\Model\Indexer $indexer,
+        \Magento\CatalogInventory\Model\Indexer\Stock\Processor $stockIndexerProcessor,
         Status $stockStatus,
         \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService,
         \Magento\CatalogInventory\Model\Stock\ItemRegistry $stockItemRegistry,
@@ -283,7 +283,7 @@ class Item extends \Magento\Framework\Model\AbstractModel
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
 
         $this->_customerSession = $customerSession;
-        $this->_indexer = $indexer;
+        $this->_stockIndexerProcessor = $stockIndexerProcessor;
         $this->_stockStatus = $stockStatus;
         $this->stockItemService = $stockItemService;
         $this->stockItemRegistry = $stockItemRegistry;
@@ -971,9 +971,7 @@ class Item extends \Magento\Framework\Model\AbstractModel
         parent::_afterSave();
 
         if ($this->_processIndexEvents) {
-            $this->_indexer->processEntityAction($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
-        } else {
-            $this->_indexer->logEvent($this, self::ENTITY, \Magento\Index\Model\Event::TYPE_SAVE);
+            $this->_stockIndexerProcessor->reindexRow($this->getProductId());
         }
         return $this;
     }
@@ -1078,4 +1076,15 @@ class Item extends \Magento\Framework\Model\AbstractModel
     {
         return false;
     }
+
+    /**
+     * Process data and set in_stock availability
+     *
+     * @return $this
+     */
+    public function processIsInStock()
+    {
+        $this->setData('is_in_stock', $this->verifyStock() ? Status::STATUS_IN_STOCK : Status::STATUS_OUT_OF_STOCK);
+        return $this;
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php b/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php
index 10aad3710111f2fe24737aaffa3f5daa7ca75dd9..33297adae80add1a7544753df6faa6a35e992ab8 100644
--- a/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php
+++ b/app/code/Magento/CatalogInventory/Service/V1/StockItemService.php
@@ -291,4 +291,16 @@ class StockItemService implements StockItemServiceInterface
         }
         return $result;
     }
+
+    /**
+     * @param int $stockData
+     * @return array
+     */
+    public function processIsInStock($stockData)
+    {
+        $stockItem = $this->stockItemRegistry->retrieve($stockData['product_id']);
+        $stockItem->setData($stockData);
+        $stockItem->processIsInStock();
+        return $stockItem->getData();
+    }
 }
diff --git a/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php b/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php
index f99ff0a56d919b2cd0cc3fe6530246066b6cc703..fedd973a47b5e91f9983ac06de0b217c6798b8e2 100644
--- a/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php
+++ b/app/code/Magento/CatalogInventory/Service/V1/StockItemServiceInterface.php
@@ -138,4 +138,10 @@ interface StockItemServiceInterface
      * @return bool
      */
     public function getIsQtyTypeIds($filter = null);
+
+    /**
+     * @param int $stockData
+     * @return array
+     */
+    public function processIsInStock($stockData);
 }
diff --git a/app/code/Magento/CatalogInventory/etc/adminhtml/system.xml b/app/code/Magento/CatalogInventory/etc/adminhtml/system.xml
index a1a9bfeeecf0c1be65558cc8bf8e2b513561aa79..3fd2fa2ab2f2c6c97c83d2cfa05b544811d055be 100644
--- a/app/code/Magento/CatalogInventory/etc/adminhtml/system.xml
+++ b/app/code/Magento/CatalogInventory/etc/adminhtml/system.xml
@@ -43,6 +43,7 @@
                     <label>Display Out of Stock Products</label>
                     <comment>Products will still be shown by direct product URLs.</comment>
                     <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
+                    <backend_model>Magento\CatalogInventory\Model\Config\Backend\ShowOutOfStock</backend_model>
                 </field>
                 <field id="stock_threshold_qty" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Only X left Threshold</label>
@@ -62,10 +63,13 @@
                     <label>Manage Stock</label>
                     <source_model>Magento\Backend\Model\Config\Source\Yesno</source_model>
                     <backend_model>Magento\CatalogInventory\Model\Config\Backend\Managestock</backend_model>
+                    <comment>Changing can take some time due to processing whole catalog.</comment>
                 </field>
                 <field id="backorders" translate="label" type="select" sortOrder="3" showInDefault="1" showInWebsite="0" showInStore="0">
                     <label>Backorders</label>
                     <source_model>Magento\CatalogInventory\Model\Source\Backorders</source_model>
+                    <backend_model>Magento\CatalogInventory\Model\Config\Backend\Backorders</backend_model>
+                    <comment>Changing can take some time due to processing whole catalog.</comment>
                 </field>
                 <field id="max_sale_qty" translate="label" type="text" sortOrder="4" showInDefault="1" showInWebsite="0" showInStore="0">
                     <label>Maximum Qty Allowed in Shopping Cart</label>
diff --git a/app/code/Magento/CatalogInventory/etc/di.xml b/app/code/Magento/CatalogInventory/etc/di.xml
index 1d3ac028b4b723200a0dfa8061982d3c6bd424ed..62c8429573b3cc51be407093e7cfbfe4f58ae545 100644
--- a/app/code/Magento/CatalogInventory/etc/di.xml
+++ b/app/code/Magento/CatalogInventory/etc/di.xml
@@ -28,7 +28,6 @@
     <preference for="Magento\CatalogInventory\Service\V1\StockItemServiceInterface" type="Magento\CatalogInventory\Service\V1\StockItemService" />
     <type name="Magento\CatalogInventory\Model\Observer">
         <arguments>
-            <argument name="resourceIndexerStock" xsi:type="object">Magento\CatalogInventory\Model\Resource\Indexer\Stock\Proxy</argument>
             <argument name="resourceStock" xsi:type="object">Magento\CatalogInventory\Model\Resource\Stock\Proxy</argument>
             <argument name="indexer" xsi:type="object">Magento\Index\Model\Indexer\Proxy</argument>
             <argument name="stock" xsi:type="object">Magento\CatalogInventory\Model\Stock\Proxy</argument>
@@ -53,4 +52,7 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Store\Model\Resource\Group">
+        <plugin name="storeGroupResourceAroundBeforeSave" type="\Magento\CatalogInventory\Model\Indexer\Stock\Plugin\StoreGroup"/>
+    </type>
 </config>
diff --git a/app/code/Magento/CatalogInventory/etc/events.xml b/app/code/Magento/CatalogInventory/etc/events.xml
index e68c5c32c5301e95c5741324a86991dbfb7d9183..d8bccc48d35815479cdeee7124c07d1c0fcbb601 100644
--- a/app/code/Magento/CatalogInventory/etc/events.xml
+++ b/app/code/Magento/CatalogInventory/etc/events.xml
@@ -72,10 +72,4 @@
     <event name="prepare_catalog_product_index_select">
         <observer name="cataloginventory" instance="Magento\CatalogInventory\Model\Observer" method="prepareCatalogProductIndexSelect" />
     </event>
-    <event name="end_index_events_cataloginventory_stock_item_save">
-        <observer name="cataloginventory" instance="Magento\CatalogInventory\Model\Observer" method="reindexProductsMassAction" />
-    </event>
-    <event name="end_process_event_cataloginventory_stock_item_save">
-        <observer name="cataloginventory" instance="Magento\CatalogInventory\Model\Observer" method="reindexProductsMassAction" />
-    </event>
 </config>
diff --git a/app/code/Magento/CatalogInventory/etc/indexer.xml b/app/code/Magento/CatalogInventory/etc/indexer.xml
new file mode 100644
index 0000000000000000000000000000000000000000..876f4c4774c1f6f71b6c6a1fe8f257a239dbb2f2
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/etc/indexer.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Indexer/etc/indexer.xsd">
+    <indexer id="cataloginventory_stock" view_id="cataloginventory_stock" class="Magento\CatalogInventory\Model\Indexer\Stock">
+        <title translate="true">Stock</title>
+        <description translate="true">Index stock</description>
+    </indexer>
+</config>
diff --git a/app/code/Magento/CatalogInventory/etc/module.xml b/app/code/Magento/CatalogInventory/etc/module.xml
index 609eab35846acdc59caaae5c76704529173564e9..3125cc3629c15b0bfe202482a7edf1f6112f05fb 100644
--- a/app/code/Magento/CatalogInventory/etc/module.xml
+++ b/app/code/Magento/CatalogInventory/etc/module.xml
@@ -34,7 +34,7 @@
             <module name="Magento_Core"/>
             <module name="Magento_Customer"/>
             <module name="Magento_Backend"/>
-            <module name="Magento_Index"/>
+            <module name="Magento_Indexer"/>
             <module name="Magento_Sales"/>
             <module name="Magento_Eav"/>
         </depends>
diff --git a/app/code/Magento/CatalogInventory/etc/mview.xml b/app/code/Magento/CatalogInventory/etc/mview.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d8b0610c517cc0ec2cbf261008cfddedfac27e64
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/etc/mview.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Mview/etc/mview.xsd">
+    <view id="cataloginventory_stock" class="Magento\CatalogInventory\Model\Indexer\Stock" group="indexer">
+        <subscriptions>
+            <table name="cataloginventory_stock_item" entity_column="product_id" />
+        </subscriptions>
+    </view>
+</config>
diff --git a/app/code/Magento/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.4-1.6.0.0.5.php b/app/code/Magento/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.4-1.6.0.0.5.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb950ab693f28667080927b6051c340295db642a
--- /dev/null
+++ b/app/code/Magento/CatalogInventory/sql/cataloginventory_setup/upgrade-1.6.0.0.4-1.6.0.0.5.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $this \Magento\Eav\Model\Entity\Setup */
+
+$this->startSetup();
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('cataloginventory_stock_status'),
+    $this->getFkName('cataloginventory_stock_status', 'stock_id', 'cataloginventory_stock', 'stock_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('cataloginventory_stock_status'),
+    $this->getFkName('cataloginventory_stock_status', 'product_id', 'catalog_product_entity', 'entity_id')
+);
+
+$this->getConnection()->dropForeignKey(
+    $this->getTable('cataloginventory_stock_status'),
+    $this->getFkName('cataloginventory_stock_status', 'website_id', 'store_website', 'website_id')
+);
+
+$this->endSetup();
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog.php
index 35b8f35f76739a67719b5c8ce5ea58e0e635f122..03eabf5f718a8f454e5bfcffb737c3dab8daea83 100644
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog.php
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog.php
@@ -36,7 +36,13 @@ class Catalog extends \Magento\Backend\Block\Widget\Grid\Container
      */
     protected function _construct()
     {
-        $this->_addButton(
+        $this->_blockGroup = 'Magento_CatalogRule';
+        $this->_controller = 'adminhtml_promo_catalog';
+        $this->_headerText = __('Catalog Price Rules');
+        $this->_addButtonLabel = __('Add New Rule');
+        parent::_construct();
+
+        $this->buttonList->add(
             'apply_rules',
             array(
                 'label' => __('Apply Rules'),
@@ -44,11 +50,5 @@ class Catalog extends \Magento\Backend\Block\Widget\Grid\Container
                 'class' => 'apply'
             )
         );
-
-        $this->_blockGroup = 'Magento_CatalogRule';
-        $this->_controller = 'adminhtml_promo_catalog';
-        $this->_headerText = __('Catalog Price Rules');
-        $this->_addButtonLabel = __('Add New Rule');
-        parent::_construct();
     }
 }
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php
index d43673c319a2c9e2121d7303be62fbbbfc114b07..9e2cf6172d2fce62a8e1ae1e13878cde676ef205 100644
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php
@@ -37,12 +37,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -66,7 +66,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_addButton(
+        $this->buttonList->add(
             'save_apply',
             array(
                 'class' => 'save',
@@ -83,7 +83,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
             )
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'save_and_continue_edit',
             array(
                 'class' => 'save',
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog.php
index b362e1a2a4945bd033a8fa335efef3b67587a176..f07ff1b3b92f6c60fd19537dab8c96656650771d 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog.php
@@ -31,12 +31,8 @@ namespace Magento\CatalogRule\Controller\Adminhtml\Promo;
 
 use Magento\Backend\App\Action;
 use Magento\Backend\App\Action\Context;
-use Magento\CatalogRule\Model\Rule\Job;
-use Magento\Framework\Model\Exception;
 use Magento\Framework\Stdlib\DateTime\Filter\Date;
 use Magento\Framework\Registry;
-use Magento\Rule\Model\Condition\AbstractCondition;
-use Magento\Rule\Model\Action\AbstractAction;
 
 class Catalog extends Action
 {
@@ -87,285 +83,6 @@ class Catalog extends Action
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Catalog Price Rules'));
-
-        $dirtyRules = $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf();
-        if ($dirtyRules->getState()) {
-            $this->messageManager->addNotice($this->getDirtyRulesNoticeMessage());
-        }
-
-        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Catalog Price Rules'));
-
-        $id = $this->getRequest()->getParam('id');
-        $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
-
-        if ($id) {
-            $model->load($id);
-            if (!$model->getRuleId()) {
-                $this->messageManager->addError(__('This rule no longer exists.'));
-                $this->_redirect('catalog_rule/*');
-                return;
-            }
-        }
-
-        $this->_title->add($model->getRuleId() ? $model->getName() : __('New Catalog Price Rule'));
-
-        // set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
-        if (!empty($data)) {
-            $model->addData($data);
-        }
-        $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
-
-        $this->_coreRegistry->register('current_promo_catalog_rule', $model);
-
-        $this->_initAction();
-        $this->_view->getLayout()->getBlock(
-            'promo_catalog_edit'
-        )->setData(
-            'action',
-            $this->getUrl('catalog_rule/promo_catalog/save')
-        );
-
-        $breadcrumb = $id ? __('Edit Rule') : __('New Rule');
-        $this->_addBreadcrumb($breadcrumb, $breadcrumb);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        if ($this->getRequest()->getPost()) {
-            try {
-                $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
-                $this->_eventManager->dispatch(
-                    'adminhtml_controller_catalogrule_prepare_save',
-                    array('request' => $this->getRequest())
-                );
-                $data = $this->getRequest()->getPost();
-                $inputFilter = new \Zend_Filter_Input(
-                    array('from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter),
-                    array(),
-                    $data
-                );
-                $data = $inputFilter->getUnescaped();
-                $id = $this->getRequest()->getParam('rule_id');
-                if ($id) {
-                    $model->load($id);
-                    if ($id != $model->getId()) {
-                        throw new Exception(__('Wrong rule specified.'));
-                    }
-                }
-
-                $validateResult = $model->validateData(new \Magento\Framework\Object($data));
-                if ($validateResult !== true) {
-                    foreach ($validateResult as $errorMessage) {
-                        $this->messageManager->addError($errorMessage);
-                    }
-                    $this->_getSession()->setPageData($data);
-                    $this->_redirect('catalog_rule/*/edit', array('id' => $model->getId()));
-                    return;
-                }
-
-                $data['conditions'] = $data['rule']['conditions'];
-                unset($data['rule']);
-
-                $model->loadPost($data);
-
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($model->getData());
-
-                $model->save();
-
-                $this->messageManager->addSuccess(__('The rule has been saved.'));
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData(false);
-                if ($this->getRequest()->getParam('auto_apply')) {
-                    $this->getRequest()->setParam('rule_id', $model->getId());
-                    $this->_forward('applyRules');
-                } else {
-                    $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(1)->save();
-                    if ($this->getRequest()->getParam('back')) {
-                        $this->_redirect('catalog_rule/*/edit', array('id' => $model->getId()));
-                        return;
-                    }
-                    $this->_redirect('catalog_rule/*/');
-                }
-                return;
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('An error occurred while saving the rule data. Please review the log and try again.')
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
-                $this->_redirect('catalog_rule/*/edit', array('id' => $this->getRequest()->getParam('rule_id')));
-                return;
-            }
-        }
-        $this->_redirect('catalog_rule/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            try {
-                $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
-                $model->load($id);
-                $model->delete();
-                $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(1)->save();
-                $this->messageManager->addSuccess(__('The rule has been deleted.'));
-                $this->_redirect('catalog_rule/*/');
-                return;
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('An error occurred while deleting the rule. Please review the log and try again.')
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->_redirect('catalog_rule/*/edit', array('id' => $this->getRequest()->getParam('id')));
-                return;
-            }
-        }
-        $this->messageManager->addError(__('Unable to find a rule to delete.'));
-        $this->_redirect('catalog_rule/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function newConditionHtmlAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
-        $type = $typeArr[0];
-
-        $model = $this->_objectManager->create(
-            $type
-        )->setId(
-            $id
-        )->setType(
-            $type
-        )->setRule(
-            $this->_objectManager->create('Magento\CatalogRule\Model\Rule')
-        )->setPrefix(
-            'conditions'
-        );
-        if (!empty($typeArr[1])) {
-            $model->setAttribute($typeArr[1]);
-        }
-
-        if ($model instanceof AbstractCondition) {
-            $model->setJsFormObject($this->getRequest()->getParam('form'));
-            $html = $model->asHtmlRecursive();
-        } else {
-            $html = '';
-        }
-        $this->getResponse()->setBody($html);
-    }
-
-    /**
-     * @return void
-     */
-    public function chooserAction()
-    {
-        if ($this->getRequest()->getParam('attribute') == 'sku') {
-            $type = 'Magento\CatalogRule\Block\Adminhtml\Promo\Widget\Chooser\Sku';
-        }
-        if (!empty($type)) {
-            $block = $this->_view->getLayout()->createBlock($type);
-            if ($block) {
-                $this->getResponse()->setBody($block->toHtml());
-            }
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function newActionHtmlAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
-        $type = $typeArr[0];
-
-        $model = $this->_objectManager->create(
-            $type
-        )->setId(
-            $id
-        )->setType(
-            $type
-        )->setRule(
-            $this->_objectManager->create('Magento\CatalogRule\Model\Rule')
-        )->setPrefix(
-            'actions'
-        );
-        if (!empty($typeArr[1])) {
-            $model->setAttribute($typeArr[1]);
-        }
-
-        if ($model instanceof AbstractAction) {
-            $model->setJsFormObject($this->getRequest()->getParam('form'));
-            $html = $model->asHtmlRecursive();
-        } else {
-            $html = '';
-        }
-        $this->getResponse()->setBody($html);
-    }
-
-    /**
-     * Apply all active catalog price rules
-     *
-     * @return void
-     */
-    public function applyRulesAction()
-    {
-        $errorMessage = __('Unable to apply rules.');
-        try {
-            /** @var Job $ruleJob */
-            $ruleJob = $this->_objectManager->get('Magento\CatalogRule\Model\Rule\Job');
-            $ruleJob->applyAll();
-
-            if ($ruleJob->hasSuccess()) {
-                $this->messageManager->addSuccess($ruleJob->getSuccess());
-                $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(0)->save();
-            } elseif ($ruleJob->hasError()) {
-                $this->messageManager->addError($errorMessage . ' ' . $ruleJob->getError());
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addError($errorMessage);
-        }
-        $this->_redirect('catalog_rule/*');
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
new file mode 100644
index 0000000000000000000000000000000000000000..84bd532607d09fdf6073909d90601d24ac178ce7
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/ApplyRules.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+use Magento\CatalogRule\Model\Rule\Job;
+
+class ApplyRules extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * Apply all active catalog price rules
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $errorMessage = __('Unable to apply rules.');
+        try {
+            /** @var Job $ruleJob */
+            $ruleJob = $this->_objectManager->get('Magento\CatalogRule\Model\Rule\Job');
+            $ruleJob->applyAll();
+
+            if ($ruleJob->hasSuccess()) {
+                $this->messageManager->addSuccess($ruleJob->getSuccess());
+                $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(0)->save();
+            } elseif ($ruleJob->hasError()) {
+                $this->messageManager->addError($errorMessage . ' ' . $ruleJob->getError());
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addError($errorMessage);
+        }
+        $this->_redirect('catalog_rule/*');
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Chooser.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Chooser.php
new file mode 100644
index 0000000000000000000000000000000000000000..10d0d77f34933fb59c5a4f33d0d1b1dbe5745c60
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Chooser.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+class Chooser extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('attribute') == 'sku') {
+            $type = 'Magento\CatalogRule\Block\Adminhtml\Promo\Widget\Chooser\Sku';
+        }
+        if (!empty($type)) {
+            $block = $this->_view->getLayout()->createBlock($type);
+            if ($block) {
+                $this->getResponse()->setBody($block->toHtml());
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..d750748978eefb95b96f54af263c57f8be8cc5e8
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+use Magento\Framework\Model\Exception;
+
+class Delete extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            try {
+                $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
+                $model->load($id);
+                $model->delete();
+                $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(1)->save();
+                $this->messageManager->addSuccess(__('The rule has been deleted.'));
+                $this->_redirect('catalog_rule/*/');
+                return;
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('An error occurred while deleting the rule. Please review the log and try again.')
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_redirect('catalog_rule/*/edit', array('id' => $this->getRequest()->getParam('id')));
+                return;
+            }
+        }
+        $this->messageManager->addError(__('Unable to find a rule to delete.'));
+        $this->_redirect('catalog_rule/*/');
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..dbfca99f9876d3510319996f91eb65cd74e93421
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+class Edit extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Catalog Price Rules'));
+
+        $id = $this->getRequest()->getParam('id');
+        $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
+
+        if ($id) {
+            $model->load($id);
+            if (!$model->getRuleId()) {
+                $this->messageManager->addError(__('This rule no longer exists.'));
+                $this->_redirect('catalog_rule/*');
+                return;
+            }
+        }
+
+        $this->_title->add($model->getRuleId() ? $model->getName() : __('New Catalog Price Rule'));
+
+        // set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
+        if (!empty($data)) {
+            $model->addData($data);
+        }
+        $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
+
+        $this->_coreRegistry->register('current_promo_catalog_rule', $model);
+
+        $this->_initAction();
+        $this->_view->getLayout()->getBlock(
+            'promo_catalog_edit'
+        )->setData(
+            'action',
+            $this->getUrl('catalog_rule/promo_catalog/save')
+        );
+
+        $breadcrumb = $id ? __('Edit Rule') : __('New Rule');
+        $this->_addBreadcrumb($breadcrumb, $breadcrumb);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Index.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b387f9599cd2c8eea5aab27ffbbc9895b90333a
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Index.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+class Index extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Catalog Price Rules'));
+
+        $dirtyRules = $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf();
+        if ($dirtyRules->getState()) {
+            $this->messageManager->addNotice($this->getDirtyRulesNoticeMessage());
+        }
+
+        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewAction.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b96ab8336c9091832c201c24e79be6fbfbcc3de
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+class NewAction extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewActionHtml.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewActionHtml.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c4314492a93937a215057f803cc36ad5fc356ff
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewActionHtml.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+use Magento\Rule\Model\Action\AbstractAction;
+
+class NewActionHtml extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
+        $type = $typeArr[0];
+
+        $model = $this->_objectManager->create(
+            $type
+        )->setId(
+            $id
+        )->setType(
+            $type
+        )->setRule(
+            $this->_objectManager->create('Magento\CatalogRule\Model\Rule')
+        )->setPrefix(
+            'actions'
+        );
+        if (!empty($typeArr[1])) {
+            $model->setAttribute($typeArr[1]);
+        }
+
+        if ($model instanceof AbstractAction) {
+            $model->setJsFormObject($this->getRequest()->getParam('form'));
+            $html = $model->asHtmlRecursive();
+        } else {
+            $html = '';
+        }
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewConditionHtml.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewConditionHtml.php
new file mode 100644
index 0000000000000000000000000000000000000000..36d5ce061f555f1e5aeda180d057bc0d65c837e9
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/NewConditionHtml.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+use Magento\Rule\Model\Condition\AbstractCondition;
+
+class NewConditionHtml extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
+        $type = $typeArr[0];
+
+        $model = $this->_objectManager->create(
+            $type
+        )->setId(
+            $id
+        )->setType(
+            $type
+        )->setRule(
+            $this->_objectManager->create('Magento\CatalogRule\Model\Rule')
+        )->setPrefix(
+            'conditions'
+        );
+        if (!empty($typeArr[1])) {
+            $model->setAttribute($typeArr[1]);
+        }
+
+        if ($model instanceof AbstractCondition) {
+            $model->setJsFormObject($this->getRequest()->getParam('form'));
+            $html = $model->asHtmlRecursive();
+        } else {
+            $html = '';
+        }
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..30e5cd9ce723dea786219132bc89007a978280eb
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog;
+
+use Magento\Framework\Model\Exception;
+
+class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getPost()) {
+            try {
+                $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
+                $this->_eventManager->dispatch(
+                    'adminhtml_controller_catalogrule_prepare_save',
+                    array('request' => $this->getRequest())
+                );
+                $data = $this->getRequest()->getPost();
+                $inputFilter = new \Zend_Filter_Input(
+                    array('from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter),
+                    array(),
+                    $data
+                );
+                $data = $inputFilter->getUnescaped();
+                $id = $this->getRequest()->getParam('rule_id');
+                if ($id) {
+                    $model->load($id);
+                    if ($id != $model->getId()) {
+                        throw new Exception(__('Wrong rule specified.'));
+                    }
+                }
+
+                $validateResult = $model->validateData(new \Magento\Framework\Object($data));
+                if ($validateResult !== true) {
+                    foreach ($validateResult as $errorMessage) {
+                        $this->messageManager->addError($errorMessage);
+                    }
+                    $this->_getSession()->setPageData($data);
+                    $this->_redirect('catalog_rule/*/edit', array('id' => $model->getId()));
+                    return;
+                }
+
+                $data['conditions'] = $data['rule']['conditions'];
+                unset($data['rule']);
+
+                $model->loadPost($data);
+
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($model->getData());
+
+                $model->save();
+
+                $this->messageManager->addSuccess(__('The rule has been saved.'));
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData(false);
+                if ($this->getRequest()->getParam('auto_apply')) {
+                    $this->getRequest()->setParam('rule_id', $model->getId());
+                    $this->_forward('applyRules');
+                } else {
+                    $this->_objectManager->create('Magento\CatalogRule\Model\Flag')->loadSelf()->setState(1)->save();
+                    if ($this->getRequest()->getParam('back')) {
+                        $this->_redirect('catalog_rule/*/edit', array('id' => $model->getId()));
+                        return;
+                    }
+                    $this->_redirect('catalog_rule/*/');
+                }
+                return;
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('An error occurred while saving the rule data. Please review the log and try again.')
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
+                $this->_redirect('catalog_rule/*/edit', array('id' => $this->getRequest()->getParam('rule_id')));
+                return;
+            }
+        }
+        $this->_redirect('catalog_rule/*/');
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Index.php
similarity index 84%
rename from app/code/Magento/CatalogRule/Controller/Adminhtml/Promo.php
rename to app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Index.php
index d456bde875b6399c3ac3be9d686277e797c40b3c..70d7fbc262322c30c8eafe2e78ef58cc228c31b9 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,34 +22,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo;
 
-/**
- * sales admin controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\CatalogRule\Controller\Adminhtml;
-
-use Magento\Backend\App\Action;
-
-class Promo extends Action
+class Index extends \Magento\Backend\App\Action
 {
     /**
-     * @return void
+     * @return bool
      */
-    public function indexAction()
+    protected function _isAllowed()
     {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_CatalogRule::promo');
-        $this->_addBreadcrumb(__('Promotions'), __('Promo'));
-        $this->_view->renderLayout();
+        return $this->_authorization->isAllowed('Magento_CatalogRule::promo');
     }
 
     /**
-     * @return bool
+     * @return void
      */
-    protected function _isAllowed()
+    public function execute()
     {
-        return $this->_authorization->isAllowed('Magento_CatalogRule::promo');
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_CatalogRule::promo');
+        $this->_addBreadcrumb(__('Promotions'), __('Promo'));
+        $this->_view->renderLayout();
     }
 }
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php
index aa41d5983ac2ab87deba70838877885f568830f7..900aad764091f11bca2aed455237b513c55bb99a 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget.php
@@ -24,82 +24,9 @@
 namespace Magento\CatalogRule\Controller\Adminhtml\Promo;
 
 use Magento\Backend\App\Action;
-use Magento\Backend\App\Action\Context;
-use Magento\Catalog\Model\Category;
-use Magento\Framework\Registry;
 
 class Widget extends Action
 {
-    /**
-     * Core registry
-     *
-     * @var Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param Context $context
-     * @param Registry $coreRegistry
-     */
-    public function __construct(Context $context, Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
-    /**
-     * Prepare block for chooser
-     *
-     * @return void
-     */
-    public function chooserAction()
-    {
-        $request = $this->getRequest();
-
-        switch ($request->getParam('attribute')) {
-            case 'sku':
-                $block = $this->_view->getLayout()->createBlock(
-                    'Magento\CatalogRule\Block\Adminhtml\Promo\Widget\Chooser\Sku',
-                    'promo_widget_chooser_sku',
-                    array('data' => array('js_form_object' => $request->getParam('form')))
-                );
-                break;
-
-            case 'category_ids':
-                $ids = $request->getParam('selected', array());
-                if (is_array($ids)) {
-                    foreach ($ids as $key => &$id) {
-                        $id = (int)$id;
-                        if ($id <= 0) {
-                            unset($ids[$key]);
-                        }
-                    }
-
-                    $ids = array_unique($ids);
-                } else {
-                    $ids = array();
-                }
-
-
-                $block = $this->_view->getLayout()->createBlock(
-                    'Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree',
-                    'promo_widget_chooser_category_ids',
-                    array('data' => array('js_form_object' => $request->getParam('form')))
-                )->setCategoryIds(
-                    $ids
-                );
-                break;
-
-            default:
-                $block = false;
-                break;
-        }
-
-        if ($block) {
-            $this->getResponse()->setBody($block->toHtml());
-        }
-    }
-
     /**
      * @return bool
      */
@@ -107,63 +34,4 @@ class Widget extends Action
     {
         return $this->_authorization->isAllowed('Magento_CatalogRule::promo_catalog');
     }
-
-    /**
-     * Get tree node (Ajax version)
-     *
-     * @return void
-     */
-    public function categoriesJsonAction()
-    {
-        $categoryId = (int)$this->getRequest()->getPost('id');
-        if ($categoryId) {
-            $this->getRequest()->setParam('id', $categoryId);
-
-            if (!($category = $this->_initCategory())) {
-                return;
-            }
-            $block = $this->_view->getLayout()->createBlock(
-                'Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree'
-            )->setCategoryIds(
-                array($categoryId)
-            );
-            $this->getResponse()->representJson(
-                $block->getTreeJson($category)
-            );
-        }
-    }
-
-    /**
-     * Initialize category object in registry
-     *
-     * @return Category
-     */
-    protected function _initCategory()
-    {
-        $categoryId = (int)$this->getRequest()->getParam('id', false);
-        $storeId = (int)$this->getRequest()->getParam('store');
-
-        $category = $this->_objectManager->create('Magento\Catalog\Model\Category');
-        $category->setStoreId($storeId);
-
-        if ($categoryId) {
-            $category->load($categoryId);
-            if ($storeId) {
-                $rootId = $this->_objectManager->get(
-                    'Magento\Store\Model\StoreManager'
-                )->getStore(
-                    $storeId
-                )->getRootCategoryId();
-                if (!in_array($rootId, $category->getPathIds())) {
-                    $this->_redirect('catalog/*/', array('_current' => true, 'id' => null));
-                    return false;
-                }
-            }
-        }
-
-        $this->_coreRegistry->register('category', $category);
-        $this->_coreRegistry->register('current_category', $category);
-
-        return $category;
-    }
 }
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..e2070d5f601ad9a5fd95bce0baf03b41b8302204
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/CategoriesJson.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Widget;
+
+use Magento\Backend\App\Action\Context;
+use Magento\Catalog\Model\Category;
+use Magento\Framework\Registry;
+
+class CategoriesJson extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Widget
+{
+    /**
+     * Core registry
+     *
+     * @var Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param Context $context
+     * @param Registry $coreRegistry
+     */
+    public function __construct(Context $context, Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Initialize category object in registry
+     *
+     * @return Category
+     */
+    protected function _initCategory()
+    {
+        $categoryId = (int)$this->getRequest()->getParam('id', false);
+        $storeId = (int)$this->getRequest()->getParam('store');
+
+        $category = $this->_objectManager->create('Magento\Catalog\Model\Category');
+        $category->setStoreId($storeId);
+
+        if ($categoryId) {
+            $category->load($categoryId);
+            if ($storeId) {
+                $rootId = $this->_objectManager->get(
+                    'Magento\Store\Model\StoreManager'
+                )->getStore(
+                    $storeId
+                )->getRootCategoryId();
+                if (!in_array($rootId, $category->getPathIds())) {
+                    $this->_redirect('catalog/*/', array('_current' => true, 'id' => null));
+                    return false;
+                }
+            }
+        }
+
+        $this->_coreRegistry->register('category', $category);
+        $this->_coreRegistry->register('current_category', $category);
+
+        return $category;
+    }
+
+    /**
+     * Get tree node (Ajax version)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $categoryId = (int)$this->getRequest()->getPost('id');
+        if ($categoryId) {
+            $this->getRequest()->setParam('id', $categoryId);
+
+            if (!($category = $this->_initCategory())) {
+                return;
+            }
+            $block = $this->_view->getLayout()->createBlock(
+                'Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree'
+            )->setCategoryIds(
+                array($categoryId)
+            );
+            $this->getResponse()->representJson(
+                $block->getTreeJson($category)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/Chooser.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/Chooser.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef68904dd1d498f22e5305cd0e42442d40893621
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Widget/Chooser.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogRule\Controller\Adminhtml\Promo\Widget;
+
+class Chooser extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Widget
+{
+    /**
+     * Prepare block for chooser
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+
+        switch ($request->getParam('attribute')) {
+            case 'sku':
+                $block = $this->_view->getLayout()->createBlock(
+                    'Magento\CatalogRule\Block\Adminhtml\Promo\Widget\Chooser\Sku',
+                    'promo_widget_chooser_sku',
+                    array('data' => array('js_form_object' => $request->getParam('form')))
+                );
+                break;
+
+            case 'category_ids':
+                $ids = $request->getParam('selected', array());
+                if (is_array($ids)) {
+                    foreach ($ids as $key => &$id) {
+                        $id = (int)$id;
+                        if ($id <= 0) {
+                            unset($ids[$key]);
+                        }
+                    }
+
+                    $ids = array_unique($ids);
+                } else {
+                    $ids = array();
+                }
+
+
+                $block = $this->_view->getLayout()->createBlock(
+                    'Magento\Catalog\Block\Adminhtml\Category\Checkboxes\Tree',
+                    'promo_widget_chooser_category_ids',
+                    array('data' => array('js_form_object' => $request->getParam('form')))
+                )->setCategoryIds(
+                    $ids
+                );
+                break;
+
+            default:
+                $block = false;
+                break;
+        }
+
+        if ($block) {
+            $this->getResponse()->setBody($block->toHtml());
+        }
+    }
+}
diff --git a/app/code/Magento/CatalogRule/etc/adminhtml/routes.xml b/app/code/Magento/CatalogRule/etc/adminhtml/routes.xml
index 64a0c96ab66eb746c8f34314627b8958cb899f0c..9d172917930ce44ca9d30209ddbb81dce93821e1 100644
--- a/app/code/Magento/CatalogRule/etc/adminhtml/routes.xml
+++ b/app/code/Magento/CatalogRule/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="catalog_rule" frontName="catalog_rule">
-            <module name="Magento_CatalogRule_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_CatalogRule" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0feb9416464d3f735ecc063a8042c4b534afa1a
--- /dev/null
+++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogSearch\Controller\Advanced;
+
+class Index extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CatalogSearch/Controller/Advanced.php b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php
similarity index 78%
rename from app/code/Magento/CatalogSearch/Controller/Advanced.php
rename to app/code/Magento/CatalogSearch/Controller/Advanced/Result.php
index 6b2cb3c897589090bab5b1ace596a9d11297da50..374328be8e7cc7886385ca1f7ef7014afeec7b3b 100644
--- a/app/code/Magento/CatalogSearch/Controller/Advanced.php
+++ b/app/code/Magento/CatalogSearch/Controller/Advanced/Result.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,20 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-/**
- * Catalog Search Controller
- *
- * @module     Catalog
- */
-namespace Magento\CatalogSearch\Controller;
+namespace Magento\CatalogSearch\Controller\Advanced;
 
 use Magento\Framework\App\Action\Context;
 use Magento\CatalogSearch\Model\Advanced as ModelAdvanced;
 use Magento\Framework\Session\Generic;
 use Magento\Framework\UrlFactory;
 
-class Advanced extends \Magento\Framework\App\Action\Action
+class Result extends \Magento\Framework\App\Action\Action
 {
     /**
      * Url factory
@@ -50,28 +45,18 @@ class Advanced extends \Magento\Framework\App\Action\Action
      */
     protected $_catalogSearchAdvanced;
 
-    /**
-     * Catalog search session
-     *
-     * @var Generic
-     */
-    protected $_catalogSearchSession;
-
     /**
      * Construct
      *
      * @param Context $context
-     * @param Generic $catalogSearchSession
      * @param ModelAdvanced $catalogSearchAdvanced
      * @param UrlFactory $urlFactory
      */
     public function __construct(
         Context $context,
-        Generic $catalogSearchSession,
         ModelAdvanced $catalogSearchAdvanced,
         UrlFactory $urlFactory
     ) {
-        $this->_catalogSearchSession = $catalogSearchSession;
         $this->_catalogSearchAdvanced = $catalogSearchAdvanced;
         $this->_urlFactory = $urlFactory;
         parent::__construct($context);
@@ -80,17 +65,7 @@ class Advanced extends \Magento\Framework\App\Action\Action
     /**
      * @return void
      */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function resultAction()
+    public function execute()
     {
         try {
             $this->_catalogSearchAdvanced->addFilters($this->getRequest()->getQuery());
diff --git a/app/code/Magento/CatalogSearch/Controller/Ajax.php b/app/code/Magento/CatalogSearch/Controller/Ajax/Suggest.php
similarity index 86%
rename from app/code/Magento/CatalogSearch/Controller/Ajax.php
rename to app/code/Magento/CatalogSearch/Controller/Ajax/Suggest.php
index 319fb28ed17e76f082e03b6728672da256d815ba..26366c432f86f74870ee3259b693fb36f8325ef0 100644
--- a/app/code/Magento/CatalogSearch/Controller/Ajax.php
+++ b/app/code/Magento/CatalogSearch/Controller/Ajax/Suggest.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,22 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\CatalogSearch\Controller\Ajax;
 
-/**
- * Catalog Search Controller
- *
- * @module     Catalog
- */
-namespace Magento\CatalogSearch\Controller;
-
-use Magento\Framework\App\Action\Action;
-
-class Ajax extends Action
+class Suggest extends \Magento\Framework\App\Action\Action
 {
     /**
      * @return void
      */
-    public function suggestAction()
+    public function execute()
     {
         if (!$this->getRequest()->getParam('q', false)) {
             $this->getResponse()->setRedirect($this->_url->getBaseUrl());
diff --git a/app/code/Magento/CatalogSearch/Controller/Result.php b/app/code/Magento/CatalogSearch/Controller/Result/Index.php
similarity index 94%
rename from app/code/Magento/CatalogSearch/Controller/Result.php
rename to app/code/Magento/CatalogSearch/Controller/Result/Index.php
index 629fefbdc9f23ba5abfbf09363f616d1d70fb15b..dcbe1c4d53d2bab52041256a6a2032868fffd3e8 100644
--- a/app/code/Magento/CatalogSearch/Controller/Result.php
+++ b/app/code/Magento/CatalogSearch/Controller/Result/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,17 +22,13 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CatalogSearch\Controller;
+namespace Magento\CatalogSearch\Controller\Result;
 
-use Magento\Framework\App\Action\Action;
 use Magento\Framework\App\Action\Context;
 use Magento\Catalog\Model\Session;
 use Magento\Store\Model\StoreManagerInterface;
 
-/**
- * Catalog Search Controller
- */
-class Result extends Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * Catalog session
@@ -62,7 +59,7 @@ class Result extends Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         /* @var $query \Magento\CatalogSearch\Model\Query */
         $query = $this->_objectManager->get('Magento\CatalogSearch\Helper\Data')->getQuery();
diff --git a/app/code/Magento/CatalogSearch/Controller/Term.php b/app/code/Magento/CatalogSearch/Controller/Term/Popular.php
similarity index 68%
rename from app/code/Magento/CatalogSearch/Controller/Term.php
rename to app/code/Magento/CatalogSearch/Controller/Term/Popular.php
index 6bae57e2463dda59dc487eb69dcdaab9ac31059b..dda99ef9f635877cef3fb7941e00798023f36790 100644
--- a/app/code/Magento/CatalogSearch/Controller/Term.php
+++ b/app/code/Magento/CatalogSearch/Controller/Term/Popular.php
@@ -21,14 +21,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CatalogSearch\Controller;
+namespace Magento\CatalogSearch\Controller\Term;
 
-use Magento\Framework\App\Action\Action;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\App\ResponseInterface;
 
-class Term extends Action
+class Popular extends \Magento\Framework\App\Action\Action
 {
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     */
+    public function __construct(\Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig)
+    {
+        $this->scopeConfig = $scopeConfig;
+    }
+
     /**
      * Dispatch request
      *
@@ -37,7 +49,11 @@ class Term extends Action
      */
     public function dispatch(RequestInterface $request)
     {
-        if (!$this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface')->getValue('catalog/seo/search_terms', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+        $searchTerms = $this->scopeConfig->getValue(
+            'catalog/seo/search_terms',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+        if (!$searchTerms) {
             $this->_redirect('noroute');
             $this->_actionFlag->set('', self::FLAG_NO_DISPATCH, true);
         }
@@ -47,7 +63,7 @@ class Term extends Action
     /**
      * @return void
      */
-    public function popularAction()
+    public function execute()
     {
         $this->_view->loadLayout();
         $this->_view->renderLayout();
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php
index 54f37d367e8c59e53a1c605d7da46cc258f8675c..b4bdfc811c8fd4315cd8785d5462123022d71823 100644
--- a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index.php
@@ -48,79 +48,12 @@ class Index extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Process validate payment data action
-     *
-     * @return void
-     */
-    public function validatePaymentDataAction()
-    {
-        $result = array();
-        try {
-            $paymentData = $this->getRequest()->getParam('payment');
-            $validator = $this->_getValidator();
-            if (!$validator) {
-                throw new \Exception('This payment method does not have centinel validation.');
-            }
-            $validator->reset();
-            $this->_getPayment()->importData($paymentData);
-            $result['authenticationUrl'] = $validator->getAuthenticationStartUrl();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result['message'] = $e->getMessage();
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $result['message'] = __('Validation failed.');
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Process autentication start action
-     *
-     * @return void
-     */
-    public function authenticationStartAction()
-    {
-        $validator = $this->_getValidator();
-        if ($validator) {
-            $this->_coreRegistry->register('current_centinel_validator', $validator);
-        }
-        $this->_view->loadLayout()->renderLayout();
-    }
-
-    /**
-     * Process autentication complete action
-     *
-     * @return void
-     */
-    public function authenticationCompleteAction()
-    {
-        try {
-            $validator = $this->_getValidator();
-            if ($validator) {
-                $request = $this->getRequest();
-
-                $data = new \Magento\Framework\Object();
-                $data->setTransactionId($request->getParam('MD'));
-                $data->setPaResPayload($request->getParam('PaRes'));
-
-                $validator->authenticate($data);
-                $this->_coreRegistry->register('current_centinel_validator', $validator);
-            }
-        } catch (\Exception $e) {
-            $this->_coreRegistry->register('current_centinel_validator', false);
-        }
-        $this->_view->loadLayout()->renderLayout();
-    }
-
     /**
      * Return payment model
      *
      * @return \Magento\Sales\Model\Quote\Payment
      */
-    private function _getPayment()
+    protected function _getPayment()
     {
         return $this->_objectManager->get('Magento\Sales\Model\AdminOrder\Create')->getQuote()->getPayment();
     }
@@ -130,7 +63,7 @@ class Index extends \Magento\Backend\App\Action
      *
      * @return \Magento\Centinel\Model\Service
      */
-    private function _getValidator()
+    protected function _getValidator()
     {
         if ($this->_getPayment()->getMethodInstance()->getIsCentinelValidationEnabled()) {
             return $this->_getPayment()->getMethodInstance()->getCentinelValidator();
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationComplete.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationComplete.php
new file mode 100644
index 0000000000000000000000000000000000000000..e9077dc6f719c6615b1ee673a4e32d4f59e92efd
--- /dev/null
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationComplete.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Centinel\Controller\Adminhtml\Centinel\Index;
+
+class AuthenticationComplete extends \Magento\Centinel\Controller\Adminhtml\Centinel\Index
+{
+    /**
+     * Process autentication complete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $validator = $this->_getValidator();
+            if ($validator) {
+                $request = $this->getRequest();
+
+                $data = new \Magento\Framework\Object();
+                $data->setTransactionId($request->getParam('MD'));
+                $data->setPaResPayload($request->getParam('PaRes'));
+
+                $validator->authenticate($data);
+                $this->_coreRegistry->register('current_centinel_validator', $validator);
+            }
+        } catch (\Exception $e) {
+            $this->_coreRegistry->register('current_centinel_validator', false);
+        }
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationStart.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationStart.php
new file mode 100644
index 0000000000000000000000000000000000000000..61f079aacdc20a7524ad089fce70d43cec65e78c
--- /dev/null
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/AuthenticationStart.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Centinel\Controller\Adminhtml\Centinel\Index;
+
+class AuthenticationStart extends \Magento\Centinel\Controller\Adminhtml\Centinel\Index
+{
+    /**
+     * Process autentication start action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $validator = $this->_getValidator();
+        if ($validator) {
+            $this->_coreRegistry->register('current_centinel_validator', $validator);
+        }
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
new file mode 100644
index 0000000000000000000000000000000000000000..503c51bb7aa76970c2e2e2f4f485dc1cccffd5a2
--- /dev/null
+++ b/app/code/Magento/Centinel/Controller/Adminhtml/Centinel/Index/ValidatePaymentData.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Centinel\Controller\Adminhtml\Centinel\Index;
+
+class ValidatePaymentData extends \Magento\Centinel\Controller\Adminhtml\Centinel\Index
+{
+    /**
+     * Process validate payment data action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $result = array();
+        try {
+            $paymentData = $this->getRequest()->getParam('payment');
+            $validator = $this->_getValidator();
+            if (!$validator) {
+                throw new \Exception('This payment method does not have centinel validation.');
+            }
+            $validator->reset();
+            $this->_getPayment()->importData($paymentData);
+            $result['authenticationUrl'] = $validator->getAuthenticationStartUrl();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result['message'] = $e->getMessage();
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $result['message'] = __('Validation failed.');
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Centinel/Controller/Index.php b/app/code/Magento/Centinel/Controller/Index.php
index 64e5ebe1b638573bd2c5b9854e7eacef062034ae..49535c4dba91c68a95a63dae1eeddd16d6ac12f9 100644
--- a/app/code/Magento/Centinel/Controller/Index.php
+++ b/app/code/Magento/Centinel/Controller/Index.php
@@ -41,57 +41,20 @@ class Index extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
         $this->_coreRegistry = $coreRegistry;
         parent::__construct($context);
     }
 
-    /**
-     * Process autentication start action
-     *
-     * @return void
-     */
-    public function authenticationStartAction()
-    {
-        $validator = $this->_getValidator();
-        if ($validator) {
-            $this->_coreRegistry->register('current_centinel_validator', $validator);
-        }
-        $this->_view->loadLayout()->renderLayout();
-    }
-
-    /**
-     * Process autentication complete action
-     *
-     * @return void
-     */
-    public function authenticationCompleteAction()
-    {
-        try {
-            $validator = $this->_getValidator();
-            if ($validator) {
-                $request = $this->getRequest();
-
-                $data = new \Magento\Framework\Object();
-                $data->setTransactionId($request->getParam('MD'));
-                $data->setPaResPayload($request->getParam('PaRes'));
-
-                $validator->authenticate($data);
-                $this->_coreRegistry->register('current_centinel_validator', $validator);
-            }
-        } catch (\Exception $e) {
-            $this->_coreRegistry->register('current_centinel_validator', false);
-        }
-        $this->_view->loadLayout()->renderLayout();
-    }
-
     /**
      * Return payment model
      *
      * @return \Magento\Sales\Model\Quote\Payment
      */
-    private function _getPayment()
+    protected function _getPayment()
     {
         return $this->_objectManager->get('Magento\Checkout\Model\Session')->getQuote()->getPayment();
     }
@@ -101,7 +64,7 @@ class Index extends \Magento\Framework\App\Action\Action
      *
      * @return \Magento\Centinel\Model\Service
      */
-    private function _getValidator()
+    protected function _getValidator()
     {
         if ($this->_getPayment()->getMethodInstance()->getIsCentinelValidationEnabled()) {
             return $this->_getPayment()->getMethodInstance()->getCentinelValidator();
diff --git a/app/code/Magento/Centinel/Controller/Index/AuthenticationComplete.php b/app/code/Magento/Centinel/Controller/Index/AuthenticationComplete.php
new file mode 100644
index 0000000000000000000000000000000000000000..96333ec9ef070a0b13356ae719b5434276d0f41e
--- /dev/null
+++ b/app/code/Magento/Centinel/Controller/Index/AuthenticationComplete.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Centinel\Controller\Index;
+
+class AuthenticationComplete extends \Magento\Centinel\Controller\Index
+{
+    /**
+     * Process autentication complete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $validator = $this->_getValidator();
+            if ($validator) {
+                $request = $this->getRequest();
+
+                $data = new \Magento\Framework\Object();
+                $data->setTransactionId($request->getParam('MD'));
+                $data->setPaResPayload($request->getParam('PaRes'));
+
+                $validator->authenticate($data);
+                $this->_coreRegistry->register('current_centinel_validator', $validator);
+            }
+        } catch (\Exception $e) {
+            $this->_coreRegistry->register('current_centinel_validator', false);
+        }
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Centinel/Controller/Index/AuthenticationStart.php b/app/code/Magento/Centinel/Controller/Index/AuthenticationStart.php
new file mode 100644
index 0000000000000000000000000000000000000000..e30d0aa8fa8c88b5b52ba364abfd356c0b01645f
--- /dev/null
+++ b/app/code/Magento/Centinel/Controller/Index/AuthenticationStart.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Centinel\Controller\Index;
+
+class AuthenticationStart extends \Magento\Centinel\Controller\Index
+{
+    /**
+     * Process autentication start action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $validator = $this->_getValidator();
+        if ($validator) {
+            $this->_coreRegistry->register('current_centinel_validator', $validator);
+        }
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php
index 5a863cb3ea0522834ef75a6386fe05e98cb11627..b0c2e2588decb7f4cf76bece3119fb5ad35802fe 100644
--- a/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php
+++ b/app/code/Magento/Checkout/Block/Cart/Item/Renderer.php
@@ -523,4 +523,18 @@ class Renderer extends \Magento\Framework\View\Element\Template implements \Mage
     {
         return $this->getLayout()->getBlock('product.price.render.default');
     }
+
+    /**
+     * Convert prices for template
+     *
+     * @param float $amount
+     * @param bool $format
+     * @return float
+     */
+    public function convertPrice($amount, $format = false)
+    {
+        $store = $this->_storeManager->getStore();
+
+        return $store->convertPrice($amount, $format);
+    }
 }
diff --git a/app/code/Magento/Checkout/Controller/Cart.php b/app/code/Magento/Checkout/Controller/Cart.php
index dda951afb238a3345903d8e7757b8121614a0e6e..865c4478acc87c5eb8d35e449f946fb3b11c5f73 100644
--- a/app/code/Magento/Checkout/Controller/Cart.php
+++ b/app/code/Magento/Checkout/Controller/Cart.php
@@ -24,11 +24,12 @@
 namespace Magento\Checkout\Controller;
 
 use Magento\Checkout\Model\Cart as CustomerCart;
+use \Magento\Catalog\Controller\Product\View\ViewInterface;
 
 /**
  * Shopping cart controller
  */
-class Cart extends \Magento\Framework\App\Action\Action implements \Magento\Catalog\Controller\Product\View\ViewInterface
+class Cart extends \Magento\Framework\App\Action\Action implements ViewInterface
 {
     /**
      * @var \Magento\Framework\App\Config\ScopeConfigInterface
@@ -107,544 +108,6 @@ class Cart extends \Magento\Framework\App\Action\Action implements \Magento\Cata
         return $this;
     }
 
-    /**
-     * Initialize product instance from request data
-     *
-     * @return \Magento\Catalog\Model\Product || false
-     */
-    protected function _initProduct()
-    {
-        $productId = (int)$this->getRequest()->getParam('product');
-        if ($productId) {
-            $storeId = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
-            $product = $this->_objectManager->create(
-                'Magento\Catalog\Model\Product'
-            )->setStoreId(
-                $storeId
-            )->load(
-                $productId
-            );
-            if ($product->getId()) {
-                return $product;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Shopping cart display action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        if ($this->cart->getQuote()->getItemsCount()) {
-            $this->cart->init();
-            $this->cart->save();
-
-            if (!$this->cart->getQuote()->validateMinimumAmount()) {
-                $currencyCode = $this->_objectManager->get(
-                    'Magento\Store\Model\StoreManagerInterface'
-                )->getStore()->getCurrentCurrencyCode();
-                $minimumAmount = $this->_objectManager->get(
-                    'Magento\Framework\Locale\CurrencyInterface'
-                )->getCurrency(
-                    $currencyCode
-                )->toCurrency(
-                    $this->_scopeConfig->getValue(
-                        'sales/minimum_order/amount',
-                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                    )
-                );
-
-                $warning = $this->_scopeConfig->getValue(
-                    'sales/minimum_order/description',
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                ) ? $this->_scopeConfig->getValue(
-                    'sales/minimum_order/description',
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                ) : __(
-                    'Minimum order amount is %1',
-                    $minimumAmount
-                );
-
-                $this->messageManager->addNotice($warning);
-            }
-        }
-
-        // Compose array of messages to add
-        $messages = array();
-        /** @var \Magento\Framework\Message\MessageInterface $message  */
-        foreach ($this->cart->getQuote()->getMessages() as $message) {
-            if ($message) {
-                // Escape HTML entities in quote message to prevent XSS
-                $message->setText($this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message->getText()));
-                $messages[] = $message;
-            }
-        }
-        $this->messageManager->addUniqueMessages($messages);
-
-        /**
-         * if customer enteres shopping cart we should mark quote
-         * as modified bc he can has checkout page in another window.
-         */
-        $this->_checkoutSession->setCartWasUpdated(true);
-
-        \Magento\Framework\Profiler::start(__METHOD__ . 'cart_display');
-
-        $this->_view->loadLayout();
-        $layout = $this->_view->getLayout();
-        $layout->initMessages();
-        $layout->getBlock('head')->setTitle(__('Shopping Cart'));
-        $this->_view->renderLayout();
-        \Magento\Framework\Profiler::stop(__METHOD__ . 'cart_display');
-    }
-
-    /**
-     * Add product to shopping cart action
-     *
-     * @return void
-     */
-    public function addAction()
-    {
-        $params = $this->getRequest()->getParams();
-        try {
-            if (isset($params['qty'])) {
-                $filter = new \Zend_Filter_LocalizedToNormalized(
-                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
-                );
-                $params['qty'] = $filter->filter($params['qty']);
-            }
-
-            $product = $this->_initProduct();
-            $related = $this->getRequest()->getParam('related_product');
-
-            /**
-             * Check product availability
-             */
-            if (!$product) {
-                $this->_goBack();
-                return;
-            }
-
-            $this->cart->addProduct($product, $params);
-            if (!empty($related)) {
-                $this->cart->addProductsByIds(explode(',', $related));
-            }
-
-            $this->cart->save();
-
-            $this->_checkoutSession->setCartWasUpdated(true);
-
-            /**
-             * @todo remove wishlist observer processAddToCart
-             */
-            $this->_eventManager->dispatch(
-                'checkout_cart_add_product_complete',
-                array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
-            );
-
-            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
-                if (!$this->cart->getQuote()->getHasError()) {
-                    $message = __(
-                        'You added %1 to your shopping cart.',
-                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName())
-                    );
-                    $this->messageManager->addSuccess($message);
-                }
-                $this->_goBack();
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            if ($this->_checkoutSession->getUseNotice(true)) {
-                $this->messageManager->addNotice(
-                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
-                );
-            } else {
-                $messages = array_unique(explode("\n", $e->getMessage()));
-                foreach ($messages as $message) {
-                    $this->messageManager->addError(
-                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
-                    );
-                }
-            }
-
-            $url = $this->_checkoutSession->getRedirectUrl(true);
-            if ($url) {
-                $this->getResponse()->setRedirect($url);
-            } else {
-                $cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
-                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($cartUrl));
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_goBack();
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function addgroupAction()
-    {
-        $orderItemIds = $this->getRequest()->getParam('order_items', array());
-        if (is_array($orderItemIds)) {
-            $itemsCollection = $this->_objectManager->create(
-                'Magento\Sales\Model\Order\Item'
-            )->getCollection()->addIdFilter(
-                $orderItemIds
-            )->load();
-            /* @var $itemsCollection \Magento\Sales\Model\Resource\Order\Item\Collection */
-            foreach ($itemsCollection as $item) {
-                try {
-                    $this->cart->addOrderItem($item, 1);
-                } catch (\Magento\Framework\Model\Exception $e) {
-                    if ($this->_checkoutSession->getUseNotice(true)) {
-                        $this->messageManager->addNotice($e->getMessage());
-                    } else {
-                        $this->messageManager->addError($e->getMessage());
-                    }
-                } catch (\Exception $e) {
-                    $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
-                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                    $this->_goBack();
-                }
-            }
-            $this->cart->save();
-            $this->_checkoutSession->setCartWasUpdated(true);
-        }
-        $this->_goBack();
-    }
-
-    /**
-     * Action to reconfigure cart item
-     *
-     * @return void
-     */
-    public function configureAction()
-    {
-        // Extract item and product to configure
-        $id = (int)$this->getRequest()->getParam('id');
-        $quoteItem = null;
-        if ($id) {
-            $quoteItem = $this->cart->getQuote()->getItemById($id);
-        }
-
-        if (!$quoteItem) {
-            $this->messageManager->addError(__("We can't find the quote item."));
-            $this->_redirect('checkout/cart');
-            return;
-        }
-
-        try {
-            $params = new \Magento\Framework\Object();
-            $params->setCategoryId(false);
-            $params->setConfigureMode(true);
-            $params->setBuyRequest($quoteItem->getBuyRequest());
-
-            $this->_objectManager->get(
-                'Magento\Catalog\Helper\Product\View'
-            )->prepareAndRender(
-                $quoteItem->getProduct()->getId(),
-                $this,
-                $params
-            );
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We cannot configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_goBack();
-            return;
-        }
-    }
-
-    /**
-     * Update product configuration for a cart item
-     *
-     * @return void
-     */
-    public function updateItemOptionsAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        $params = $this->getRequest()->getParams();
-
-        if (!isset($params['options'])) {
-            $params['options'] = array();
-        }
-        try {
-            if (isset($params['qty'])) {
-                $filter = new \Zend_Filter_LocalizedToNormalized(
-                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
-                );
-                $params['qty'] = $filter->filter($params['qty']);
-            }
-
-            $quoteItem = $this->cart->getQuote()->getItemById($id);
-            if (!$quoteItem) {
-                throw new \Magento\Framework\Model\Exception(__("We can't find the quote item."));
-            }
-
-            $item = $this->cart->updateItem($id, new \Magento\Framework\Object($params));
-            if (is_string($item)) {
-                throw new \Magento\Framework\Model\Exception($item);
-            }
-            if ($item->getHasError()) {
-                throw new \Magento\Framework\Model\Exception($item->getMessage());
-            }
-
-            $related = $this->getRequest()->getParam('related_product');
-            if (!empty($related)) {
-                $this->cart->addProductsByIds(explode(',', $related));
-            }
-
-            $this->cart->save();
-
-            $this->_checkoutSession->setCartWasUpdated(true);
-
-            $this->_eventManager->dispatch(
-                'checkout_cart_update_item_complete',
-                array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
-            );
-            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
-                if (!$this->cart->getQuote()->getHasError()) {
-                    $message = __(
-                        '%1 was updated in your shopping cart.',
-                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($item->getProduct()->getName())
-                    );
-                    $this->messageManager->addSuccess($message);
-                }
-                $this->_goBack();
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            if ($this->_checkoutSession->getUseNotice(true)) {
-                $this->messageManager->addNotice($e->getMessage());
-            } else {
-                $messages = array_unique(explode("\n", $e->getMessage()));
-                foreach ($messages as $message) {
-                    $this->messageManager->addError($message);
-                }
-            }
-
-            $url = $this->_checkoutSession->getRedirectUrl(true);
-            if ($url) {
-                $this->getResponse()->setRedirect($url);
-            } else {
-                $cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
-                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($cartUrl));
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We cannot update the item.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_goBack();
-        }
-        $this->_redirect('*/*');
-    }
-
-    /**
-     * Update shopping cart data action
-     *
-     * @return void
-     */
-    public function updatePostAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        $updateAction = (string)$this->getRequest()->getParam('update_cart_action');
-
-        switch ($updateAction) {
-            case 'empty_cart':
-                $this->_emptyShoppingCart();
-                break;
-            case 'update_qty':
-                $this->_updateShoppingCart();
-                break;
-            default:
-                $this->_updateShoppingCart();
-        }
-
-        $this->_goBack();
-    }
-
-    /**
-     * Update customer's shopping cart
-     *
-     * @return void
-     */
-    protected function _updateShoppingCart()
-    {
-        try {
-            $cartData = $this->getRequest()->getParam('cart');
-            if (is_array($cartData)) {
-                $filter = new \Zend_Filter_LocalizedToNormalized(
-                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
-                );
-                foreach ($cartData as $index => $data) {
-                    if (isset($data['qty'])) {
-                        $cartData[$index]['qty'] = $filter->filter(trim($data['qty']));
-                    }
-                }
-                if (!$this->cart->getCustomerSession()->getCustomerId() && $this->cart->getQuote()->getCustomerId()) {
-                    $this->cart->getQuote()->setCustomerId(null);
-                }
-
-                $cartData = $this->cart->suggestItemsQty($cartData);
-                $this->cart->updateItems($cartData)->save();
-            }
-            $this->_checkoutSession->setCartWasUpdated(true);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError(
-                $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
-            );
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We cannot update the shopping cart.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Empty customer's shopping cart
-     *
-     * @return void
-     */
-    protected function _emptyShoppingCart()
-    {
-        try {
-            $this->cart->truncate()->save();
-            $this->_checkoutSession->setCartWasUpdated(true);
-        } catch (\Magento\Framework\Model\Exception $exception) {
-            $this->messageManager->addError($exception->getMessage());
-        } catch (\Exception $exception) {
-            $this->messageManager->addException($exception, __('We cannot update the shopping cart.'));
-        }
-    }
-
-    /**
-     * Delete shopping cart item action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        if ($id) {
-            try {
-                $this->cart->removeItem($id)->save();
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('We cannot remove the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-        }
-        $defaultUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*');
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($defaultUrl));
-    }
-
-    /**
-     * Initialize shipping information
-     *
-     * @return void
-     */
-    public function estimatePostAction()
-    {
-        $country = (string)$this->getRequest()->getParam('country_id');
-        $postcode = (string)$this->getRequest()->getParam('estimate_postcode');
-        $city = (string)$this->getRequest()->getParam('estimate_city');
-        $regionId = (string)$this->getRequest()->getParam('region_id');
-        $region = (string)$this->getRequest()->getParam('region');
-
-        $this->cart->getQuote()->getShippingAddress()->setCountryId(
-            $country
-        )->setCity(
-            $city
-        )->setPostcode(
-            $postcode
-        )->setRegionId(
-            $regionId
-        )->setRegion(
-            $region
-        )->setCollectShippingRates(
-            true
-        );
-        $this->cart->getQuote()->save();
-        $this->_goBack();
-    }
-
-    /**
-     * @return void
-     */
-    public function estimateUpdatePostAction()
-    {
-        $code = (string)$this->getRequest()->getParam('estimate_method');
-        if (!empty($code)) {
-            $this->cart->getQuote()->getShippingAddress()->setShippingMethod($code)->save();
-        }
-        $this->_goBack();
-    }
-
-    /**
-     * Initialize coupon
-     *
-     * @return void
-     */
-    public function couponPostAction()
-    {
-        /**
-         * No reason continue with empty shopping cart
-         */
-        if (!$this->cart->getQuote()->getItemsCount()) {
-            $this->_goBack();
-            return;
-        }
-
-        $couponCode = $this->getRequest()->getParam(
-            'remove'
-        ) == 1 ? '' : trim(
-            $this->getRequest()->getParam('coupon_code')
-        );
-        $oldCouponCode = $this->cart->getQuote()->getCouponCode();
-
-        if (!strlen($couponCode) && !strlen($oldCouponCode)) {
-            $this->_goBack();
-            return;
-        }
-
-        try {
-            $codeLength = strlen($couponCode);
-            $isCodeLengthValid = $codeLength && $codeLength <= \Magento\Checkout\Helper\Cart::COUPON_CODE_MAX_LENGTH;
-
-            $this->cart->getQuote()->getShippingAddress()->setCollectShippingRates(true);
-            $this->cart->getQuote()->setCouponCode($isCodeLengthValid ? $couponCode : '')->collectTotals()->save();
-
-            if ($codeLength) {
-                if ($isCodeLengthValid && $couponCode == $this->cart->getQuote()->getCouponCode()) {
-                    $this->messageManager->addSuccess(
-                        __(
-                            'The coupon code "%1" was applied.',
-                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($couponCode)
-                        )
-                    );
-                } else {
-                    $this->messageManager->addError(
-                        __(
-                            'The coupon code "%1" is not valid.',
-                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($couponCode)
-                        )
-                    );
-                }
-            } else {
-                $this->messageManager->addSuccess(__('The coupon code was canceled.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We cannot apply the coupon code.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        $this->_goBack();
-    }
-
     /**
      * Check if URL corresponds store
      *
diff --git a/app/code/Magento/Checkout/Controller/Cart/Add.php b/app/code/Magento/Checkout/Controller/Cart/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6cc05214d12b621cb38d9ba50dd0c2e051ec2aa
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/Add.php
@@ -0,0 +1,134 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class Add extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Initialize product instance from request data
+     *
+     * @return \Magento\Catalog\Model\Product || false
+     */
+    protected function _initProduct()
+    {
+        $productId = (int)$this->getRequest()->getParam('product');
+        if ($productId) {
+            $storeId = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getId();
+            $product = $this->_objectManager->create(
+                'Magento\Catalog\Model\Product'
+            )->setStoreId(
+                $storeId
+            )->load(
+                $productId
+            );
+            if ($product->getId()) {
+                return $product;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Add product to shopping cart action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $params = $this->getRequest()->getParams();
+        try {
+            if (isset($params['qty'])) {
+                $filter = new \Zend_Filter_LocalizedToNormalized(
+                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
+                );
+                $params['qty'] = $filter->filter($params['qty']);
+            }
+
+            $product = $this->_initProduct();
+            $related = $this->getRequest()->getParam('related_product');
+
+            /**
+             * Check product availability
+             */
+            if (!$product) {
+                $this->_goBack();
+                return;
+            }
+
+            $this->cart->addProduct($product, $params);
+            if (!empty($related)) {
+                $this->cart->addProductsByIds(explode(',', $related));
+            }
+
+            $this->cart->save();
+
+            $this->_checkoutSession->setCartWasUpdated(true);
+
+            /**
+             * @todo remove wishlist observer processAddToCart
+             */
+            $this->_eventManager->dispatch(
+                'checkout_cart_add_product_complete',
+                array('product' => $product, 'request' => $this->getRequest(), 'response' => $this->getResponse())
+            );
+
+            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
+                if (!$this->cart->getQuote()->getHasError()) {
+                    $message = __(
+                        'You added %1 to your shopping cart.',
+                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName())
+                    );
+                    $this->messageManager->addSuccess($message);
+                }
+                $this->_goBack();
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            if ($this->_checkoutSession->getUseNotice(true)) {
+                $this->messageManager->addNotice(
+                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
+                );
+            } else {
+                $messages = array_unique(explode("\n", $e->getMessage()));
+                foreach ($messages as $message) {
+                    $this->messageManager->addError(
+                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message)
+                    );
+                }
+            }
+
+            $url = $this->_checkoutSession->getRedirectUrl(true);
+            if ($url) {
+                $this->getResponse()->setRedirect($url);
+            } else {
+                $cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
+                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($cartUrl));
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_goBack();
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/Addgroup.php b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb91dd8a555637f5f940be3853942f408e0caf45
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/Addgroup.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class Addgroup extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $orderItemIds = $this->getRequest()->getParam('order_items', array());
+        if (is_array($orderItemIds)) {
+            $itemsCollection = $this->_objectManager->create(
+                'Magento\Sales\Model\Order\Item'
+            )->getCollection()->addIdFilter(
+                $orderItemIds
+            )->load();
+            /* @var $itemsCollection \Magento\Sales\Model\Resource\Order\Item\Collection */
+            foreach ($itemsCollection as $item) {
+                try {
+                    $this->cart->addOrderItem($item, 1);
+                } catch (\Magento\Framework\Model\Exception $e) {
+                    if ($this->_checkoutSession->getUseNotice(true)) {
+                        $this->messageManager->addNotice($e->getMessage());
+                    } else {
+                        $this->messageManager->addError($e->getMessage());
+                    }
+                } catch (\Exception $e) {
+                    $this->messageManager->addException($e, __('We cannot add this item to your shopping cart'));
+                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    $this->_goBack();
+                }
+            }
+            $this->cart->save();
+            $this->_checkoutSession->setCartWasUpdated(true);
+        }
+        $this->_goBack();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/Configure.php b/app/code/Magento/Checkout/Controller/Cart/Configure.php
new file mode 100644
index 0000000000000000000000000000000000000000..f387ff7e8c1902f5a4e3ce27ada771d5752c20c1
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/Configure.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class Configure extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Action to reconfigure cart item
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // Extract item and product to configure
+        $id = (int)$this->getRequest()->getParam('id');
+        $quoteItem = null;
+        if ($id) {
+            $quoteItem = $this->cart->getQuote()->getItemById($id);
+        }
+
+        if (!$quoteItem) {
+            $this->messageManager->addError(__("We can't find the quote item."));
+            $this->_redirect('checkout/cart');
+            return;
+        }
+
+        try {
+            $params = new \Magento\Framework\Object();
+            $params->setCategoryId(false);
+            $params->setConfigureMode(true);
+            $params->setBuyRequest($quoteItem->getBuyRequest());
+
+            $this->_objectManager->get(
+                'Magento\Catalog\Helper\Product\View'
+            )->prepareAndRender(
+                $quoteItem->getProduct()->getId(),
+                $this,
+                $params
+            );
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We cannot configure the product.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_goBack();
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/CouponPost.php b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1bc4812fdc4c72fe97bf930b197c0760a38cc5e
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/CouponPost.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class CouponPost extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Initialize coupon
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /**
+         * No reason continue with empty shopping cart
+         */
+        if (!$this->cart->getQuote()->getItemsCount()) {
+            $this->_goBack();
+            return;
+        }
+
+        $couponCode = $this->getRequest()->getParam(
+            'remove'
+        ) == 1 ? '' : trim(
+            $this->getRequest()->getParam('coupon_code')
+        );
+        $oldCouponCode = $this->cart->getQuote()->getCouponCode();
+
+        if (!strlen($couponCode) && !strlen($oldCouponCode)) {
+            $this->_goBack();
+            return;
+        }
+
+        try {
+            $codeLength = strlen($couponCode);
+            $isCodeLengthValid = $codeLength && $codeLength <= \Magento\Checkout\Helper\Cart::COUPON_CODE_MAX_LENGTH;
+
+            $this->cart->getQuote()->getShippingAddress()->setCollectShippingRates(true);
+            $this->cart->getQuote()->setCouponCode($isCodeLengthValid ? $couponCode : '')->collectTotals()->save();
+
+            if ($codeLength) {
+                if ($isCodeLengthValid && $couponCode == $this->cart->getQuote()->getCouponCode()) {
+                    $this->messageManager->addSuccess(
+                        __(
+                            'The coupon code "%1" was applied.',
+                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($couponCode)
+                        )
+                    );
+                } else {
+                    $this->messageManager->addError(
+                        __(
+                            'The coupon code "%1" is not valid.',
+                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($couponCode)
+                        )
+                    );
+                }
+            } else {
+                $this->messageManager->addSuccess(__('The coupon code was canceled.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We cannot apply the coupon code.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        $this->_goBack();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/Delete.php b/app/code/Magento/Checkout/Controller/Cart/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..a54c34d9033d4a186fe36de8fc041c446b7457cb
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/Delete.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class Delete extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Delete shopping cart item action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        if ($id) {
+            try {
+                $this->cart->removeItem($id)->save();
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('We cannot remove the item.'));
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+        }
+        $defaultUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*');
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($defaultUrl));
+    }
+}
diff --git a/app/code/Magento/Captcha/Controller/Refresh.php b/app/code/Magento/Checkout/Controller/Cart/EstimatePost.php
similarity index 52%
rename from app/code/Magento/Captcha/Controller/Refresh.php
rename to app/code/Magento/Checkout/Controller/Cart/EstimatePost.php
index f505d6cd974ad6a2c85b002a82af5273a6b3abe2..3531213b4dca86b8a9c09bbff4e570162e5bacc7 100644
--- a/app/code/Magento/Captcha/Controller/Refresh.php
+++ b/app/code/Magento/Checkout/Controller/Cart/EstimatePost.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,33 +22,37 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Captcha\Controller;
+namespace Magento\Checkout\Controller\Cart;
 
-/**
- * Captcha controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Refresh extends \Magento\Framework\App\Action\Action
+class EstimatePost extends \Magento\Checkout\Controller\Cart
 {
     /**
-     * Refreshes captcha and returns JSON encoded URL to image (AJAX action)
-     * Example: {'imgSrc': 'http://example.com/media/captcha/67842gh187612ngf8s.png'}
+     * Initialize shipping information
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
-        $formId = $this->getRequest()->getPost('formId');
-        $captchaModel = $this->_objectManager->get('Magento\Captcha\Helper\Data')->getCaptcha($formId);
-        $this->_view->getLayout()->createBlock(
-            $captchaModel->getBlockName()
-        )->setFormId(
-            $formId
-        )->setIsAjax(
+        $country = (string)$this->getRequest()->getParam('country_id');
+        $postcode = (string)$this->getRequest()->getParam('estimate_postcode');
+        $city = (string)$this->getRequest()->getParam('estimate_city');
+        $regionId = (string)$this->getRequest()->getParam('region_id');
+        $region = (string)$this->getRequest()->getParam('region');
+
+        $this->cart->getQuote()->getShippingAddress()->setCountryId(
+            $country
+        )->setCity(
+            $city
+        )->setPostcode(
+            $postcode
+        )->setRegionId(
+            $regionId
+        )->setRegion(
+            $region
+        )->setCollectShippingRates(
             true
-        )->toHtml();
-        $this->getResponse()->representJson(json_encode(array('imgSrc' => $captchaModel->getImgSrc())));
-        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+        );
+        $this->cart->getQuote()->save();
+        $this->_goBack();
     }
 }
diff --git a/app/code/Magento/Checkout/Controller/Cart/EstimateUpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/EstimateUpdatePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..d29bf83521863721d48fadfdce0a6030fd625355
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/EstimateUpdatePost.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class EstimateUpdatePost extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $code = (string)$this->getRequest()->getParam('estimate_method');
+        if (!empty($code)) {
+            $this->cart->getQuote()->getShippingAddress()->setShippingMethod($code)->save();
+        }
+        $this->_goBack();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/Index.php b/app/code/Magento/Checkout/Controller/Cart/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..10e0e0d11ce1ccdd0105cfa2a50211b7a89c3e19
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/Index.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class Index extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Shopping cart display action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->cart->getQuote()->getItemsCount()) {
+            $this->cart->init();
+            $this->cart->save();
+
+            if (!$this->cart->getQuote()->validateMinimumAmount()) {
+                $currencyCode = $this->_objectManager->get(
+                    'Magento\Store\Model\StoreManagerInterface'
+                )->getStore()->getCurrentCurrencyCode();
+                $minimumAmount = $this->_objectManager->get(
+                    'Magento\Framework\Locale\CurrencyInterface'
+                )->getCurrency(
+                    $currencyCode
+                )->toCurrency(
+                    $this->_scopeConfig->getValue(
+                        'sales/minimum_order/amount',
+                        \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                    )
+                );
+
+                $warning = $this->_scopeConfig->getValue(
+                    'sales/minimum_order/description',
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                ) ? $this->_scopeConfig->getValue(
+                    'sales/minimum_order/description',
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                ) : __(
+                    'Minimum order amount is %1',
+                    $minimumAmount
+                );
+
+                $this->messageManager->addNotice($warning);
+            }
+        }
+
+        // Compose array of messages to add
+        $messages = array();
+        /** @var \Magento\Framework\Message\MessageInterface $message  */
+        foreach ($this->cart->getQuote()->getMessages() as $message) {
+            if ($message) {
+                // Escape HTML entities in quote message to prevent XSS
+                $message->setText($this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($message->getText()));
+                $messages[] = $message;
+            }
+        }
+        $this->messageManager->addUniqueMessages($messages);
+
+        /**
+         * if customer enteres shopping cart we should mark quote
+         * as modified bc he can has checkout page in another window.
+         */
+        $this->_checkoutSession->setCartWasUpdated(true);
+
+        \Magento\Framework\Profiler::start(__METHOD__ . 'cart_display');
+
+        $this->_view->loadLayout();
+        $layout = $this->_view->getLayout();
+        $layout->initMessages();
+        $layout->getBlock('head')->setTitle(__('Shopping Cart'));
+        $this->_view->renderLayout();
+        \Magento\Framework\Profiler::stop(__METHOD__ . 'cart_display');
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a45938f6689b6b60b8b4fd20ac59a40639ef570
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdateItemOptions.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class UpdateItemOptions extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Update product configuration for a cart item
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        $params = $this->getRequest()->getParams();
+
+        if (!isset($params['options'])) {
+            $params['options'] = array();
+        }
+        try {
+            if (isset($params['qty'])) {
+                $filter = new \Zend_Filter_LocalizedToNormalized(
+                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
+                );
+                $params['qty'] = $filter->filter($params['qty']);
+            }
+
+            $quoteItem = $this->cart->getQuote()->getItemById($id);
+            if (!$quoteItem) {
+                throw new \Magento\Framework\Model\Exception(__("We can't find the quote item."));
+            }
+
+            $item = $this->cart->updateItem($id, new \Magento\Framework\Object($params));
+            if (is_string($item)) {
+                throw new \Magento\Framework\Model\Exception($item);
+            }
+            if ($item->getHasError()) {
+                throw new \Magento\Framework\Model\Exception($item->getMessage());
+            }
+
+            $related = $this->getRequest()->getParam('related_product');
+            if (!empty($related)) {
+                $this->cart->addProductsByIds(explode(',', $related));
+            }
+
+            $this->cart->save();
+
+            $this->_checkoutSession->setCartWasUpdated(true);
+
+            $this->_eventManager->dispatch(
+                'checkout_cart_update_item_complete',
+                array('item' => $item, 'request' => $this->getRequest(), 'response' => $this->getResponse())
+            );
+            if (!$this->_checkoutSession->getNoCartRedirect(true)) {
+                if (!$this->cart->getQuote()->getHasError()) {
+                    $message = __(
+                        '%1 was updated in your shopping cart.',
+                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($item->getProduct()->getName())
+                    );
+                    $this->messageManager->addSuccess($message);
+                }
+                $this->_goBack();
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            if ($this->_checkoutSession->getUseNotice(true)) {
+                $this->messageManager->addNotice($e->getMessage());
+            } else {
+                $messages = array_unique(explode("\n", $e->getMessage()));
+                foreach ($messages as $message) {
+                    $this->messageManager->addError($message);
+                }
+            }
+
+            $url = $this->_checkoutSession->getRedirectUrl(true);
+            if ($url) {
+                $this->getResponse()->setRedirect($url);
+            } else {
+                $cartUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
+                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($cartUrl));
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We cannot update the item.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_goBack();
+        }
+        $this->_redirect('*/*');
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce806dd440374fdd3e83bc8caaa981ef4d35a90a
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Cart/UpdatePost.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Cart;
+
+class UpdatePost extends \Magento\Checkout\Controller\Cart
+{
+    /**
+     * Empty customer's shopping cart
+     *
+     * @return void
+     */
+    protected function _emptyShoppingCart()
+    {
+        try {
+            $this->cart->truncate()->save();
+            $this->_checkoutSession->setCartWasUpdated(true);
+        } catch (\Magento\Framework\Model\Exception $exception) {
+            $this->messageManager->addError($exception->getMessage());
+        } catch (\Exception $exception) {
+            $this->messageManager->addException($exception, __('We cannot update the shopping cart.'));
+        }
+    }
+
+    /**
+     * Update customer's shopping cart
+     *
+     * @return void
+     */
+    protected function _updateShoppingCart()
+    {
+        try {
+            $cartData = $this->getRequest()->getParam('cart');
+            if (is_array($cartData)) {
+                $filter = new \Zend_Filter_LocalizedToNormalized(
+                    array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
+                );
+                foreach ($cartData as $index => $data) {
+                    if (isset($data['qty'])) {
+                        $cartData[$index]['qty'] = $filter->filter(trim($data['qty']));
+                    }
+                }
+                if (!$this->cart->getCustomerSession()->getCustomerId() && $this->cart->getQuote()->getCustomerId()) {
+                    $this->cart->getQuote()->setCustomerId(null);
+                }
+
+                $cartData = $this->cart->suggestItemsQty($cartData);
+                $this->cart->updateItems($cartData)->save();
+            }
+            $this->_checkoutSession->setCartWasUpdated(true);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError(
+                $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($e->getMessage())
+            );
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We cannot update the shopping cart.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+
+    /**
+     * Update shopping cart data action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        $updateAction = (string)$this->getRequest()->getParam('update_cart_action');
+
+        switch ($updateAction) {
+            case 'empty_cart':
+                $this->_emptyShoppingCart();
+                break;
+            case 'update_qty':
+                $this->_updateShoppingCart();
+                break;
+            default:
+                $this->_updateShoppingCart();
+        }
+
+        $this->_goBack();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Index.php b/app/code/Magento/Checkout/Controller/Index/Index.php
similarity index 93%
rename from app/code/Magento/Checkout/Controller/Index.php
rename to app/code/Magento/Checkout/Controller/Index/Index.php
index f860f7174ab8e853cc0e74da33b78d17466e848f..45dd47516a9dfa2c73a61c34ac6c36be3ab41716 100644
--- a/app/code/Magento/Checkout/Controller/Index.php
+++ b/app/code/Magento/Checkout/Controller/Index/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Checkout\Controller;
+namespace Magento\Checkout\Controller\Index;
 
 class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->_redirect('checkout/onepage', array('_secure' => true));
     }
diff --git a/app/code/Magento/Checkout/Controller/Onepage.php b/app/code/Magento/Checkout/Controller/Onepage.php
index 6e3c6b7b7b8ad77e2b0f9de4807f5259d603214f..7daee3e4bc336d5fbe8b713015dc64e3437e384b 100755
--- a/app/code/Magento/Checkout/Controller/Onepage.php
+++ b/app/code/Magento/Checkout/Controller/Onepage.php
@@ -185,24 +185,6 @@ class Onepage extends Action
         return $this->_getHtmlByHandle('checkout_onepage_paymentmethod');
     }
 
-    /**
-     * @return string
-     */
-    protected function _getAdditionalHtml()
-    {
-        return $this->_getHtmlByHandle('checkout_onepage_additional');
-    }
-
-    /**
-     * Get order review step html
-     *
-     * @return string
-     */
-    protected function _getReviewHtml()
-    {
-        return $this->_getHtmlByHandle('checkout_onepage_review');
-    }
-
     /**
      * Get one page checkout model
      *
@@ -213,451 +195,6 @@ class Onepage extends Action
         return $this->_objectManager->get('Magento\Checkout\Model\Type\Onepage');
     }
 
-    /**
-     * Checkout page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        if (!$this->_objectManager->get('Magento\Checkout\Helper\Data')->canOnepageCheckout()) {
-            $this->messageManager->addError(__('The onepage checkout is disabled.'));
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $quote = $this->getOnepage()->getQuote();
-        if (!$quote->hasItems() || $quote->getHasError() || !$quote->validateMinimumAmount()) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-
-        $this->_objectManager->get('Magento\Checkout\Model\Session')->setCartWasUpdated(false);
-        $currentUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*/*', array('_secure' => true));
-        $this->_objectManager->get('Magento\Customer\Model\Session')->setBeforeAuthUrl($currentUrl);
-        $this->getOnepage()->initCheckout();
-        $this->_view->loadLayout();
-        $layout = $this->_view->getLayout();
-        $layout->initMessages();
-        $layout->getBlock('head')->setTitle(__('Checkout'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Checkout status block
-     *
-     * @return void
-     */
-    public function progressAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        $this->_view->addPageLayoutHandles();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function shippingMethodAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        $this->_view->addPageLayoutHandles();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function reviewAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        $this->_view->addPageLayoutHandles();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Order success action
-     *
-     * @return void
-     */
-    public function successAction()
-    {
-        $session = $this->getOnepage()->getCheckout();
-        if (!$this->_objectManager->get('Magento\Checkout\Model\Session\SuccessValidator')->isValid($session)) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $session->clearQuote();
-        //@todo: Refactor it to match CQRS
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_eventManager->dispatch(
-            'checkout_onepage_controller_success_action',
-            array('order_ids' => array($session->getLastOrderId()))
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function failureAction()
-    {
-        $lastQuoteId = $this->getOnepage()->getCheckout()->getLastQuoteId();
-        $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
-
-        if (!$lastQuoteId || !$lastOrderId) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function getAdditionalAction()
-    {
-        $this->getResponse()->setBody($this->_getAdditionalHtml());
-    }
-
-    /**
-     * Save checkout method
-     *
-     * @return void
-     */
-    public function saveMethodAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        if ($this->getRequest()->isPost()) {
-            $method = $this->getRequest()->getPost('method');
-            $result = $this->getOnepage()->saveCheckoutMethod($method);
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Save checkout billing address
-     *
-     * @return void
-     */
-    public function saveBillingAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        if ($this->getRequest()->isPost()) {
-            $data = $this->getRequest()->getPost('billing', array());
-            $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
-
-            if (isset($data['email'])) {
-                $data['email'] = trim($data['email']);
-            }
-            $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
-
-            if (!isset($result['error'])) {
-                if ($this->getOnepage()->getQuote()->isVirtual()) {
-                    $result['goto_section'] = 'payment';
-                    $result['update_section'] = array(
-                        'name' => 'payment-method',
-                        'html' => $this->_getPaymentMethodsHtml()
-                    );
-                } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
-                    $result['goto_section'] = 'shipping_method';
-                    $result['update_section'] = array(
-                        'name' => 'shipping-method',
-                        'html' => $this->_getShippingMethodsHtml()
-                    );
-
-                    $result['allow_sections'] = array('shipping');
-                    $result['duplicateBillingInfo'] = 'true';
-                } else {
-                    $result['goto_section'] = 'shipping';
-                }
-            }
-
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Shipping address save action
-     *
-     * @return void
-     */
-    public function saveShippingAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        if ($this->getRequest()->isPost()) {
-            $data = $this->getRequest()->getPost('shipping', array());
-            $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
-            $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
-
-            if (!isset($result['error'])) {
-                $result['goto_section'] = 'shipping_method';
-                $result['update_section'] = array(
-                    'name' => 'shipping-method',
-                    'html' => $this->_getShippingMethodsHtml()
-                );
-            }
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Shipping method save action
-     *
-     * @return void
-     */
-    public function saveShippingMethodAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        if ($this->getRequest()->isPost()) {
-            $data = $this->getRequest()->getPost('shipping_method', '');
-            $result = $this->getOnepage()->saveShippingMethod($data);
-            // $result will contain error data if shipping method is empty
-            if (!$result) {
-                $this->_eventManager->dispatch(
-                    'checkout_controller_onepage_save_shipping_method',
-                    array('request' => $this->getRequest(), 'quote' => $this->getOnepage()->getQuote())
-                );
-                $this->getOnepage()->getQuote()->collectTotals();
-                $this->getResponse()->representJson(
-                    $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-                );
-
-                $result['goto_section'] = 'payment';
-                $result['update_section'] = array(
-                    'name' => 'payment-method',
-                    'html' => $this->_getPaymentMethodsHtml()
-                );
-            }
-            $this->getOnepage()->getQuote()->collectTotals()->save();
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Save payment ajax action
-     *
-     * Sets either redirect or a JSON response
-     *
-     * @return void
-     */
-    public function savePaymentAction()
-    {
-        if ($this->_expireAjax()) {
-            return;
-        }
-        try {
-            if (!$this->getRequest()->isPost()) {
-                $this->_ajaxRedirectResponse();
-                return;
-            }
-
-            $data = $this->getRequest()->getPost('payment', array());
-            $result = $this->getOnepage()->savePayment($data);
-
-            // get section and redirect data
-            $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
-            if (empty($result['error']) && !$redirectUrl) {
-                $result['goto_section'] = 'review';
-                $result['update_section'] = array('name' => 'review', 'html' => $this->_getReviewHtml());
-            }
-            if ($redirectUrl) {
-                $result['redirect'] = $redirectUrl;
-            }
-        } catch (\Magento\Payment\Exception $e) {
-            if ($e->getFields()) {
-                $result['fields'] = $e->getFields();
-            }
-            $result['error'] = $e->getMessage();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result['error'] = $e->getMessage();
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $result['error'] = __('Unable to set Payment Method');
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Get Order by quoteId
-     *
-     * @return \Magento\Sales\Model\Order
-     * @throws \Magento\Payment\Model\Info\Exception
-     */
-    protected function _getOrder()
-    {
-        if (is_null($this->_order)) {
-            $this->_order = $this->_objectManager->create('Magento\Sales\Model\Order');
-            $this->_order->load($this->getOnepage()->getQuote()->getId(), 'quote_id');
-            if (!$this->_order->getId()) {
-                throw new \Magento\Payment\Model\Info\Exception(__('Can not create invoice. Order was not found.'));
-            }
-        }
-        return $this->_order;
-    }
-
-    /**
-     * Create invoice
-     *
-     * @return \Magento\Sales\Model\Order\Invoice
-     */
-    protected function _initInvoice()
-    {
-        $items = array();
-        foreach ($this->_getOrder()->getAllItems() as $item) {
-            $items[$item->getId()] = $item->getQtyOrdered();
-        }
-        /* @var $invoice \Magento\Sales\Model\Service\Order */
-        $invoice = $this->_objectManager->create(
-            'Magento\Sales\Model\Service\Order',
-            array('order' => $this->_getOrder())
-        )->prepareInvoice(
-            $items
-        );
-        $invoice->setEmailSent(true)->register();
-
-        $this->_coreRegistry->register('current_invoice', $invoice);
-        return $invoice;
-    }
-
-    /**
-     * Create order action
-     *
-     * @return void
-     */
-    public function saveOrderAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        if ($this->_expireAjax()) {
-            return;
-        }
-
-        $result = array();
-        try {
-            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
-            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', array())))) {
-                $result['success'] = false;
-                $result['error'] = true;
-                $result['error_messages'] = __(
-                    'Please agree to all the terms and conditions before placing the order.'
-                );
-                $this->getResponse()->representJson(
-                    $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-                );
-                return;
-            }
-
-            $data = $this->getRequest()->getPost('payment', array());
-            if ($data) {
-                $data['checks'] = array(
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
-                );
-                $this->getOnepage()->getQuote()->getPayment()->importData($data);
-            }
-
-            $this->getOnepage()->saveOrder();
-
-            $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
-            $result['success'] = true;
-            $result['error'] = false;
-        } catch (\Magento\Payment\Model\Info\Exception $e) {
-            $message = $e->getMessage();
-            if (!empty($message)) {
-                $result['error_messages'] = $message;
-            }
-            $result['goto_section'] = 'payment';
-            $result['update_section'] = array('name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml());
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_objectManager->get(
-                'Magento\Checkout\Helper\Data'
-            )->sendPaymentFailedEmail(
-                $this->getOnepage()->getQuote(),
-                $e->getMessage()
-            );
-            $result['success'] = false;
-            $result['error'] = true;
-            $result['error_messages'] = $e->getMessage();
-            $gotoSection = $this->getOnepage()->getCheckout()->getGotoSection();
-            if ($gotoSection) {
-                $result['goto_section'] = $gotoSection;
-                $this->getOnepage()->getCheckout()->setGotoSection(null);
-            }
-
-            $updateSection = $this->getOnepage()->getCheckout()->getUpdateSection();
-            if ($updateSection) {
-                if (isset($this->_sectionUpdateFunctions[$updateSection])) {
-                    $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
-                    $result['update_section'] = array(
-                        'name' => $updateSection,
-                        'html' => $this->{$updateSectionFunction}()
-                    );
-                }
-                $this->getOnepage()->getCheckout()->setUpdateSection(null);
-            }
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_objectManager->get(
-                'Magento\Checkout\Helper\Data'
-            )->sendPaymentFailedEmail(
-                $this->getOnepage()->getQuote(),
-                $e->getMessage()
-            );
-            $result['success'] = false;
-            $result['error'] = true;
-            $result['error_messages'] = __('Something went wrong processing your order. Please try again later.');
-        }
-        $this->getOnepage()->getQuote()->save();
-        /**
-         * when there is redirect to third party, we don't want to save order yet.
-         * we will save the order in return action.
-         */
-        if (isset($redirectUrl)) {
-            $result['redirect'] = $redirectUrl;
-        }
-
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
     /**
      * Check can page show for unregistered users
      *
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Failure.php b/app/code/Magento/Checkout/Controller/Onepage/Failure.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac1e65d378458b6880009ff982516cddec7ccae2
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/Failure.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class Failure extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $lastQuoteId = $this->getOnepage()->getCheckout()->getLastQuoteId();
+        $lastOrderId = $this->getOnepage()->getCheckout()->getLastOrderId();
+
+        if (!$lastQuoteId || !$lastOrderId) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Grid/Collection.php b/app/code/Magento/Checkout/Controller/Onepage/GetAdditional.php
similarity index 71%
rename from app/code/Magento/Tax/Model/Resource/Calculation/Grid/Collection.php
rename to app/code/Magento/Checkout/Controller/Onepage/GetAdditional.php
index 4837228aa897567deae5f4f221f8a55a8a64daff..1a4ab6a3f3af7a9cd88b5e1bd03d49faab9883d9 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation/Grid/Collection.php
+++ b/app/code/Magento/Checkout/Controller/Onepage/GetAdditional.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,26 +22,23 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Checkout\Controller\Onepage;
 
-
-/**
- * Tax Calculation Collection
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Tax\Model\Resource\Calculation\Grid;
-
-class Collection extends \Magento\Tax\Model\Resource\Calculation\Rate\Collection
+class GetAdditional extends \Magento\Checkout\Controller\Onepage
 {
     /**
-     * Join Region Table
-     *
      * @return string
      */
-    protected function _initSelect()
+    protected function _getAdditionalHtml()
+    {
+        return $this->_getHtmlByHandle('checkout_onepage_additional');
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
     {
-        parent::_initSelect();
-        $this->joinRegionTable();
-        return $this;
+        $this->getResponse()->setBody($this->_getAdditionalHtml());
     }
 }
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Index.php b/app/code/Magento/Checkout/Controller/Onepage/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..a9e34d5ef0b98eade7f279681ebd646d4d53dd6e
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/Index.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class Index extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Checkout page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_objectManager->get('Magento\Checkout\Helper\Data')->canOnepageCheckout()) {
+            $this->messageManager->addError(__('The onepage checkout is disabled.'));
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $quote = $this->getOnepage()->getQuote();
+        if (!$quote->hasItems() || $quote->getHasError() || !$quote->validateMinimumAmount()) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+
+        $this->_objectManager->get('Magento\Checkout\Model\Session')->setCartWasUpdated(false);
+        $currentUrl = $this->_objectManager->create('Magento\Framework\UrlInterface')
+            ->getUrl(
+                '*/*/*',
+                array('_secure' => true)
+            );
+        $this->_objectManager->get('Magento\Customer\Model\Session')->setBeforeAuthUrl($currentUrl);
+        $this->getOnepage()->initCheckout();
+        $this->_view->loadLayout();
+        $layout = $this->_view->getLayout();
+        $layout->initMessages();
+        $layout->getBlock('head')->setTitle(__('Checkout'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Progress.php b/app/code/Magento/Checkout/Controller/Onepage/Progress.php
new file mode 100644
index 0000000000000000000000000000000000000000..77cc210ae39d0f17cb91498dd4562d240189e3d1
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/Progress.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ * Checkout status block
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class Progress extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        $this->_view->addPageLayoutHandles();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Review.php b/app/code/Magento/Checkout/Controller/Onepage/Review.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7980d9b277e15a9957e7737afffbbd7bd8bc407
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/Review.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class Review extends Progress
+{
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveBilling.php b/app/code/Magento/Checkout/Controller/Onepage/SaveBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..057ba86941034888d31642ee4efee12a27c1b66c
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveBilling.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SaveBilling extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Save checkout billing address
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        if ($this->getRequest()->isPost()) {
+            $data = $this->getRequest()->getPost('billing', array());
+            $customerAddressId = $this->getRequest()->getPost('billing_address_id', false);
+
+            if (isset($data['email'])) {
+                $data['email'] = trim($data['email']);
+            }
+            $result = $this->getOnepage()->saveBilling($data, $customerAddressId);
+
+            if (!isset($result['error'])) {
+                if ($this->getOnepage()->getQuote()->isVirtual()) {
+                    $result['goto_section'] = 'payment';
+                    $result['update_section'] = array(
+                        'name' => 'payment-method',
+                        'html' => $this->_getPaymentMethodsHtml()
+                    );
+                } elseif (isset($data['use_for_shipping']) && $data['use_for_shipping'] == 1) {
+                    $result['goto_section'] = 'shipping_method';
+                    $result['update_section'] = array(
+                        'name' => 'shipping-method',
+                        'html' => $this->_getShippingMethodsHtml()
+                    );
+
+                    $result['allow_sections'] = array('shipping');
+                    $result['duplicateBillingInfo'] = 'true';
+                } else {
+                    $result['goto_section'] = 'shipping';
+                }
+            }
+
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveMethod.php b/app/code/Magento/Checkout/Controller/Onepage/SaveMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f19f09d29712540b64dd6cac68a7eb86bb76a20
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveMethod.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SaveMethod extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Save checkout method
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        if ($this->getRequest()->isPost()) {
+            $method = $this->getRequest()->getPost('method');
+            $result = $this->getOnepage()->saveCheckoutMethod($method);
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b44744969fc68c3ecaf3b6ee4f848cf8c6fd91e
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveOrder.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SaveOrder extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Create order action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        if ($this->_expireAjax()) {
+            return;
+        }
+
+        $result = array();
+        try {
+            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
+            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', array())))) {
+                $result['success'] = false;
+                $result['error'] = true;
+                $result['error_messages'] = __(
+                    'Please agree to all the terms and conditions before placing the order.'
+                );
+                $this->getResponse()->representJson(
+                    $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+                );
+                return;
+            }
+
+            $data = $this->getRequest()->getPost('payment', array());
+            if ($data) {
+                $data['checks'] = array(
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_CHECKOUT,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
+                );
+                $this->getOnepage()->getQuote()->getPayment()->importData($data);
+            }
+
+            $this->getOnepage()->saveOrder();
+
+            $redirectUrl = $this->getOnepage()->getCheckout()->getRedirectUrl();
+            $result['success'] = true;
+            $result['error'] = false;
+        } catch (\Magento\Payment\Model\Info\Exception $e) {
+            $message = $e->getMessage();
+            if (!empty($message)) {
+                $result['error_messages'] = $message;
+            }
+            $result['goto_section'] = 'payment';
+            $result['update_section'] = array('name' => 'payment-method', 'html' => $this->_getPaymentMethodsHtml());
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get(
+                'Magento\Checkout\Helper\Data'
+            )->sendPaymentFailedEmail(
+                $this->getOnepage()->getQuote(),
+                $e->getMessage()
+            );
+            $result['success'] = false;
+            $result['error'] = true;
+            $result['error_messages'] = $e->getMessage();
+            $gotoSection = $this->getOnepage()->getCheckout()->getGotoSection();
+            if ($gotoSection) {
+                $result['goto_section'] = $gotoSection;
+                $this->getOnepage()->getCheckout()->setGotoSection(null);
+            }
+
+            $updateSection = $this->getOnepage()->getCheckout()->getUpdateSection();
+            if ($updateSection) {
+                if (isset($this->_sectionUpdateFunctions[$updateSection])) {
+                    $updateSectionFunction = $this->_sectionUpdateFunctions[$updateSection];
+                    $result['update_section'] = array(
+                        'name' => $updateSection,
+                        'html' => $this->{$updateSectionFunction}()
+                    );
+                }
+                $this->getOnepage()->getCheckout()->setUpdateSection(null);
+            }
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get(
+                'Magento\Checkout\Helper\Data'
+            )->sendPaymentFailedEmail(
+                $this->getOnepage()->getQuote(),
+                $e->getMessage()
+            );
+            $result['success'] = false;
+            $result['error'] = true;
+            $result['error_messages'] = __('Something went wrong processing your order. Please try again later.');
+        }
+        $this->getOnepage()->getQuote()->save();
+        /**
+         * when there is redirect to third party, we don't want to save order yet.
+         * we will save the order in return action.
+         */
+        if (isset($redirectUrl)) {
+            $result['redirect'] = $redirectUrl;
+        }
+
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..854562b517bde88cc2de3f9a71f4ee9a5d030383
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SavePayment.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SavePayment extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Get order review step html
+     *
+     * @return string
+     */
+    protected function _getReviewHtml()
+    {
+        return $this->_getHtmlByHandle('checkout_onepage_review');
+    }
+
+    /**
+     * Save payment ajax action
+     *
+     * Sets either redirect or a JSON response
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        try {
+            if (!$this->getRequest()->isPost()) {
+                $this->_ajaxRedirectResponse();
+                return;
+            }
+
+            $data = $this->getRequest()->getPost('payment', array());
+            $result = $this->getOnepage()->savePayment($data);
+
+            // get section and redirect data
+            $redirectUrl = $this->getOnepage()->getQuote()->getPayment()->getCheckoutRedirectUrl();
+            if (empty($result['error']) && !$redirectUrl) {
+                $result['goto_section'] = 'review';
+                $result['update_section'] = array('name' => 'review', 'html' => $this->_getReviewHtml());
+            }
+            if ($redirectUrl) {
+                $result['redirect'] = $redirectUrl;
+            }
+        } catch (\Magento\Payment\Exception $e) {
+            if ($e->getFields()) {
+                $result['fields'] = $e->getFields();
+            }
+            $result['error'] = $e->getMessage();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result['error'] = $e->getMessage();
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $result['error'] = __('Unable to set Payment Method');
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveShipping.php b/app/code/Magento/Checkout/Controller/Onepage/SaveShipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..87c9ddb83bde6ff63802d004a497b15ef4fead70
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveShipping.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SaveShipping extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Shipping address save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        if ($this->getRequest()->isPost()) {
+            $data = $this->getRequest()->getPost('shipping', array());
+            $customerAddressId = $this->getRequest()->getPost('shipping_address_id', false);
+            $result = $this->getOnepage()->saveShipping($data, $customerAddressId);
+
+            if (!isset($result['error'])) {
+                $result['goto_section'] = 'shipping_method';
+                $result['update_section'] = array(
+                    'name' => 'shipping-method',
+                    'html' => $this->_getShippingMethodsHtml()
+                );
+            }
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/SaveShippingMethod.php b/app/code/Magento/Checkout/Controller/Onepage/SaveShippingMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..9558349a0a120d5f6319cc8f50273a93d9a103b9
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/SaveShippingMethod.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class SaveShippingMethod extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Shipping method save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        if ($this->getRequest()->isPost()) {
+            $data = $this->getRequest()->getPost('shipping_method', '');
+            $result = $this->getOnepage()->saveShippingMethod($data);
+            // $result will contain error data if shipping method is empty
+            if (!$result) {
+                $this->_eventManager->dispatch(
+                    'checkout_controller_onepage_save_shipping_method',
+                    array('request' => $this->getRequest(), 'quote' => $this->getOnepage()->getQuote())
+                );
+                $this->getOnepage()->getQuote()->collectTotals();
+                $this->getResponse()->representJson(
+                    $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+                );
+
+                $result['goto_section'] = 'payment';
+                $result['update_section'] = array(
+                    'name' => 'payment-method',
+                    'html' => $this->_getPaymentMethodsHtml()
+                );
+            }
+            $this->getOnepage()->getQuote()->collectTotals()->save();
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/ShippingMethod.php b/app/code/Magento/Checkout/Controller/Onepage/ShippingMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e9eee0f21cc156c09e1df18fd89e163a5f7eabe
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/ShippingMethod.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class ShippingMethod extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_expireAjax()) {
+            return;
+        }
+        $this->_view->addPageLayoutHandles();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Checkout/Controller/Onepage/Success.php b/app/code/Magento/Checkout/Controller/Onepage/Success.php
new file mode 100644
index 0000000000000000000000000000000000000000..346c08a420ef1ff66ce1bf08b3798851b4d11bd7
--- /dev/null
+++ b/app/code/Magento/Checkout/Controller/Onepage/Success.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Controller\Onepage;
+
+class Success extends \Magento\Checkout\Controller\Onepage
+{
+    /**
+     * Order success action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->getOnepage()->getCheckout();
+        if (!$this->_objectManager->get('Magento\Checkout\Model\Session\SuccessValidator')->isValid($session)) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $session->clearQuote();
+        //@todo: Refactor it to match CQRS
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_eventManager->dispatch(
+            'checkout_onepage_controller_success_action',
+            array('order_ids' => array($session->getLastOrderId()))
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Checkout/i18n/de_DE.csv b/app/code/Magento/Checkout/i18n/de_DE.csv
index 6a5ca89aa0ac69e86a890974f55da199d9a41d93..f604546621d384fcec4417d7242a93722eae4d98 100644
--- a/app/code/Magento/Checkout/i18n/de_DE.csv
+++ b/app/code/Magento/Checkout/i18n/de_DE.csv
@@ -52,7 +52,6 @@ State/Province,Staat/Provinz
 "The onepage checkout is disabled.","Der Bezahlvorgang mit nur einer Seite ist deaktiviert."
 Checkout,Checkout
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Bitte Stimmen Sie allen Geschäftsbedingungen vor Auftragserteilung zu."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/en_US.csv b/app/code/Magento/Checkout/i18n/en_US.csv
index 9cb4953b000757e41c0228c1f52a4181a1868bf2..60b459d0ba9a722d2f98e3f9c6efcad7d19af30d 100644
--- a/app/code/Magento/Checkout/i18n/en_US.csv
+++ b/app/code/Magento/Checkout/i18n/en_US.csv
@@ -52,7 +52,6 @@ State/Province,State/Province
 "The onepage checkout is disabled.","The onepage checkout is disabled."
 Checkout,Checkout
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Please agree to all the terms and conditions before placing the order."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/es_ES.csv b/app/code/Magento/Checkout/i18n/es_ES.csv
index 2f14185a1f256e3f61cda59d8661c58f626aac0c..3c66daf827db3bb8eacb054b9c14b249ce5bc1de 100644
--- a/app/code/Magento/Checkout/i18n/es_ES.csv
+++ b/app/code/Magento/Checkout/i18n/es_ES.csv
@@ -52,7 +52,6 @@ State/Province,Estado/Provincia
 "The onepage checkout is disabled.","El pago por página está deshabilitado."
 Checkout,Pedido
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Debe manifestar su conformidad con todos los términos y condiciones antes de hacer el pedido."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/fr_FR.csv b/app/code/Magento/Checkout/i18n/fr_FR.csv
index 034a262eb4240bf282ff36c21aa6db25be70cc00..84f388d8db5a26eb858a53aff8249d14f877ee67 100644
--- a/app/code/Magento/Checkout/i18n/fr_FR.csv
+++ b/app/code/Magento/Checkout/i18n/fr_FR.csv
@@ -52,7 +52,6 @@ State/Province,Etat/pays
 "The onepage checkout is disabled.","L'encart pour passer la commande est désactivé."
 Checkout,Paiement
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Veuillez agréer à tous les termes et conditions avant de passer commande."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/nl_NL.csv b/app/code/Magento/Checkout/i18n/nl_NL.csv
index 08c79333d5863bb3809addc9c0146f6bb9b40fb0..99e59069beacdb0eb96c97759ce4426540e4d286 100644
--- a/app/code/Magento/Checkout/i18n/nl_NL.csv
+++ b/app/code/Magento/Checkout/i18n/nl_NL.csv
@@ -52,7 +52,6 @@ State/Province,staat/provincie
 "The onepage checkout is disabled.","Afrekenen op een pagina is uitgeschakeld."
 Checkout,Betalen
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Gelieve in te stemmen met de algemene voorwaarden voor het plaatsen van de bestelling."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/pt_BR.csv b/app/code/Magento/Checkout/i18n/pt_BR.csv
index 92b3452c02f6a39176552dfcab02de7f2c3381a6..3262a6a301b512ea7b320572b3d6cece9da4792f 100644
--- a/app/code/Magento/Checkout/i18n/pt_BR.csv
+++ b/app/code/Magento/Checkout/i18n/pt_BR.csv
@@ -52,7 +52,6 @@ State/Province,Estado/Província
 "The onepage checkout is disabled.","O checkout de uma página está desativado."
 Checkout,"Encerrar Compra"
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.","Por favor concorde com todos os Termos e Condições antes de colocar a ordem."
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/Checkout/i18n/zh_CN.csv b/app/code/Magento/Checkout/i18n/zh_CN.csv
index 5f6e8376b3725805b73c20c8c37b3ce7b63fcde9..e7d99aa2b4dfcd6d686a30b91d1f28f216488c6d 100644
--- a/app/code/Magento/Checkout/i18n/zh_CN.csv
+++ b/app/code/Magento/Checkout/i18n/zh_CN.csv
@@ -52,7 +52,6 @@ State/Province,州/省
 "The onepage checkout is disabled.",单页面结账已被禁用。
 Checkout,结账
 "Unable to set Payment Method","Unable to set Payment Method"
-"Can not create invoice. Order was not found.","Can not create invoice. Order was not found."
 "Please agree to all the terms and conditions before placing the order.",请在下订单前同意所有的条款和条件。
 "Something went wrong processing your order. Please try again later.","Something went wrong processing your order. Please try again later."
 "We can't find the product.","We can't find the product."
diff --git a/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit.php b/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit.php
index 5aadeb9d1ae05204c2e6ca2dfb93377f885b37d5..778b24681d7ded18174dea761fb2d6814f985cd5 100644
--- a/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit.php
+++ b/app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Edit.php
@@ -33,12 +33,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -59,8 +59,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Condition'));
-        $this->_updateButton('delete', 'label', __('Delete Condition'));
+        $this->buttonList->update('save', 'label', __('Save Condition'));
+        $this->buttonList->update('delete', 'label', __('Delete Condition'));
     }
 
     /**
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement.php
index f2d7f0f935bacff7773f0b683f38d7ed3442db33..661963f3f3526e2492d98e126af2cf2800710598 100644
--- a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement.php
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement.php
@@ -42,124 +42,6 @@ class Agreement extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Terms and Conditions'));
-
-        $this->_initAction()->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\CheckoutAgreements\Block\Adminhtml\Agreement')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Terms and Conditions'));
-
-        $id = $this->getRequest()->getParam('id');
-        $agreementModel = $this->_objectManager->create('Magento\CheckoutAgreements\Model\Agreement');
-
-        if ($id) {
-            $agreementModel->load($id);
-            if (!$agreementModel->getId()) {
-                $this->messageManager->addError(__('This condition no longer exists.'));
-                $this->_redirect('checkout/*/');
-                return;
-            }
-        }
-
-        $this->_title->add($agreementModel->getId() ? $agreementModel->getName() : __('New Condition'));
-
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getAgreementData(true);
-        if (!empty($data)) {
-            $agreementModel->setData($data);
-        }
-
-        $this->_coreRegistry->register('checkout_agreement', $agreementModel);
-
-        $this->_initAction()->_addBreadcrumb(
-            $id ? __('Edit Condition') : __('New Condition'),
-            $id ? __('Edit Condition') : __('New Condition')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\CheckoutAgreements\Block\Adminhtml\Agreement\Edit'
-            )->setData(
-                'action',
-                $this->getUrl('checkout/*/save')
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        $postData = $this->getRequest()->getPost();
-        if ($postData) {
-            $model = $this->_objectManager->get('Magento\CheckoutAgreements\Model\Agreement');
-            $model->setData($postData);
-
-            try {
-                $model->save();
-
-                $this->messageManager->addSuccess(__('The condition has been saved.'));
-                $this->_redirect('checkout/*/');
-
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Something went wrong while saving this condition.'));
-            }
-
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setAgreementData($postData);
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        $model = $this->_objectManager->get('Magento\CheckoutAgreements\Model\Agreement')->load($id);
-        if (!$model->getId()) {
-            $this->messageManager->addError(__('This condition no longer exists.'));
-            $this->_redirect('checkout/*/');
-            return;
-        }
-
-        try {
-            $model->delete();
-            $this->messageManager->addSuccess(__('The condition has been deleted.'));
-            $this->_redirect('checkout/*/');
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('Something went wrong  while deleting this condition.'));
-        }
-
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
     /**
      * Initialize action
      *
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Delete.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ef679f0eead72c6f5e7ad16d5c9a52e5d82f7ff
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Delete.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CheckoutAgreements\Controller\Adminhtml\Agreement;
+
+class Delete extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        $model = $this->_objectManager->get('Magento\CheckoutAgreements\Model\Agreement')->load($id);
+        if (!$model->getId()) {
+            $this->messageManager->addError(__('This condition no longer exists.'));
+            $this->_redirect('checkout/*/');
+            return;
+        }
+
+        try {
+            $model->delete();
+            $this->messageManager->addSuccess(__('The condition has been deleted.'));
+            $this->_redirect('checkout/*/');
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('Something went wrong  while deleting this condition.'));
+        }
+
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Edit.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..70957bba2d0f5b7030c526b79ebef5899b5e0490
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Edit.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CheckoutAgreements\Controller\Adminhtml\Agreement;
+
+class Edit extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Terms and Conditions'));
+
+        $id = $this->getRequest()->getParam('id');
+        $agreementModel = $this->_objectManager->create('Magento\CheckoutAgreements\Model\Agreement');
+
+        if ($id) {
+            $agreementModel->load($id);
+            if (!$agreementModel->getId()) {
+                $this->messageManager->addError(__('This condition no longer exists.'));
+                $this->_redirect('checkout/*/');
+                return;
+            }
+        }
+
+        $this->_title->add($agreementModel->getId() ? $agreementModel->getName() : __('New Condition'));
+
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getAgreementData(true);
+        if (!empty($data)) {
+            $agreementModel->setData($data);
+        }
+
+        $this->_coreRegistry->register('checkout_agreement', $agreementModel);
+
+        $this->_initAction()->_addBreadcrumb(
+            $id ? __('Edit Condition') : __('New Condition'),
+            $id ? __('Edit Condition') : __('New Condition')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\CheckoutAgreements\Block\Adminhtml\Agreement\Edit'
+            )->setData(
+                'action',
+                $this->getUrl('checkout/*/save')
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Index.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..a855f67a37acfac7721ae30f4c2c97d8a1e94680
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CheckoutAgreements\Controller\Adminhtml\Agreement;
+
+class Index extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Terms and Conditions'));
+
+        $this->_initAction()->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\CheckoutAgreements\Block\Adminhtml\Agreement')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/NewAction.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d38bbb64ac5050d9d21528848b38fcbf8e346b9
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CheckoutAgreements\Controller\Adminhtml\Agreement;
+
+class NewAction extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..24073ded5ab984ff14becf1cf3a8d504e578d2ec
--- /dev/null
+++ b/app/code/Magento/CheckoutAgreements/Controller/Adminhtml/Agreement/Save.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CheckoutAgreements\Controller\Adminhtml\Agreement;
+
+class Save extends \Magento\CheckoutAgreements\Controller\Adminhtml\Agreement
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $postData = $this->getRequest()->getPost();
+        if ($postData) {
+            $model = $this->_objectManager->get('Magento\CheckoutAgreements\Model\Agreement');
+            $model->setData($postData);
+
+            try {
+                $model->save();
+
+                $this->messageManager->addSuccess(__('The condition has been saved.'));
+                $this->_redirect('checkout/*/');
+
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong while saving this condition.'));
+            }
+
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setAgreementData($postData);
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+        }
+    }
+}
diff --git a/app/code/Magento/CheckoutAgreements/etc/adminhtml/routes.xml b/app/code/Magento/CheckoutAgreements/etc/adminhtml/routes.xml
index 6dfdfbaee24b02389fb2b655b56b9ec0b52e9a0b..52d1bd8bca18a85cf6d04aad88382fcca2aee439 100644
--- a/app/code/Magento/CheckoutAgreements/etc/adminhtml/routes.xml
+++ b/app/code/Magento/CheckoutAgreements/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="checkout" frontName="checkout">
-            <module name="Magento_CheckoutAgreements_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_CheckoutAgreements" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit.php b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit.php
index 9fc51a13a5c15ee2e7f0f991cde6310d17b31aa3..7282704da1df68dc176e660782cd2724eeaf480a 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Block/Edit.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Block/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -60,10 +60,10 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Block'));
-        $this->_updateButton('delete', 'label', __('Delete Block'));
+        $this->buttonList->update('save', 'label', __('Save Block'));
+        $this->buttonList->update('delete', 'label', __('Delete Block'));
 
-        $this->_addButton(
+        $this->buttonList->add(
             'saveandcontinue',
             array(
                 'label' => __('Save and Continue Edit'),
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page.php b/app/code/Magento/Cms/Block/Adminhtml/Page.php
index 6484ceaa46c88468d7ba015740bbffdd3e1da70f..8698553496a44d721b74e750f95a62110cfb4417 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page.php
@@ -42,9 +42,9 @@ class Page extends \Magento\Backend\Block\Widget\Grid\Container
         parent::_construct();
 
         if ($this->_isAllowedAction('Magento_Cms::save')) {
-            $this->_updateButton('add', 'label', __('Add New Page'));
+            $this->buttonList->update('add', 'label', __('Add New Page'));
         } else {
-            $this->_removeButton('add');
+            $this->buttonList->remove('add');
         }
     }
 
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit.php b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit.php
index 41d4bd8a66e442ece24f2f336b7c8f1b19f5eab7..7c57a5463dab99a700b285e4ce0f415d00adf811 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Page/Edit.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Page/Edit.php
@@ -38,12 +38,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -65,8 +65,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         parent::_construct();
 
         if ($this->_isAllowedAction('Magento_Cms::save')) {
-            $this->_updateButton('save', 'label', __('Save Page'));
-            $this->_addButton(
+            $this->buttonList->update('save', 'label', __('Save Page'));
+            $this->buttonList->add(
                 'saveandcontinue',
                 array(
                     'label' => __('Save and Continue Edit'),
@@ -80,13 +80,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                 -100
             );
         } else {
-            $this->_removeButton('save');
+            $this->buttonList->remove('save');
         }
 
         if ($this->_isAllowedAction('Magento_Cms::page_delete')) {
-            $this->_updateButton('delete', 'label', __('Delete Page'));
+            $this->buttonList->update('delete', 'label', __('Delete Page'));
         } else {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
     }
 
diff --git a/app/code/Magento/Cms/Block/Adminhtml/Wysiwyg/Images/Content.php b/app/code/Magento/Cms/Block/Adminhtml/Wysiwyg/Images/Content.php
index 49c04d49bab4288a8794a61ec09dd0d7e1b134ef..6798fb562efc65cade62e138f5eba36c4611c46d 100644
--- a/app/code/Magento/Cms/Block/Adminhtml/Wysiwyg/Images/Content.php
+++ b/app/code/Magento/Cms/Block/Adminhtml/Wysiwyg/Images/Content.php
@@ -36,12 +36,12 @@ class Content extends \Magento\Backend\Block\Widget\Container
     protected $_jsonEncoder;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Json\EncoderInterface $jsonEncoder,
         array $data = array()
     ) {
@@ -58,23 +58,24 @@ class Content extends \Magento\Backend\Block\Widget\Container
     {
         parent::_construct();
         $this->_headerText = __('Media Storage');
-        $this->_removeButton('back')->_removeButton('edit');
-        $this->_addButton(
+        $this->buttonList->remove('back');
+        $this->buttonList->remove('edit');
+        $this->buttonList->add(
             'new_folder',
             array('class' => 'save', 'label' => __('Create Folder...'), 'type' => 'button')
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'delete_folder',
             array('class' => 'delete no-display', 'label' => __('Delete Folder'), 'type' => 'button')
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'delete_files',
             array('class' => 'delete no-display', 'label' => __('Delete File'), 'type' => 'button')
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'insert_files',
             array('class' => 'save no-display primary', 'label' => __('Insert File'), 'type' => 'button')
         );
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block.php b/app/code/Magento/Cms/Controller/Adminhtml/Block.php
index b2135e4e3071b63fe46e0e694d314f0aed994b13..54a90de7cc9e2554a362b7939f462c7ed749b7eb 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Block.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block.php
@@ -68,158 +68,6 @@ class Block extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Blocks'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new CMS block
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        // the same form is used to create and edit
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit CMS block
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Blocks'));
-
-        // 1. Get ID and create model
-        $id = $this->getRequest()->getParam('block_id');
-        $model = $this->_objectManager->create('Magento\Cms\Model\Block');
-
-        // 2. Initial checking
-        if ($id) {
-            $model->load($id);
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This block no longer exists.'));
-                $this->_redirect('*/*/');
-                return;
-            }
-        }
-
-        $this->_title->add($model->getId() ? $model->getTitle() : __('New Block'));
-
-        // 3. Set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
-        if (!empty($data)) {
-            $model->setData($data);
-        }
-
-        // 4. Register model to use later in blocks
-        $this->_coreRegistry->register('cms_block', $model);
-
-        // 5. Build edit form
-        $this->_initAction()->_addBreadcrumb(
-            $id ? __('Edit Block') : __('New Block'),
-            $id ? __('Edit Block') : __('New Block')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        // check if data sent
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $id = $this->getRequest()->getParam('block_id');
-            $model = $this->_objectManager->create('Magento\Cms\Model\Block')->load($id);
-            if (!$model->getId() && $id) {
-                $this->messageManager->addError(__('This block no longer exists.'));
-                $this->_redirect('*/*/');
-                return;
-            }
-
-            // init model and set data
-
-            $model->setData($data);
-
-            // try to save it
-            try {
-                // save the data
-                $model->save();
-                // display success message
-                $this->messageManager->addSuccess(__('The block has been saved.'));
-                // clear previously saved data from session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
-
-                // check if 'Save and Continue'
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('*/*/edit', array('block_id' => $model->getId()));
-                    return;
-                }
-                // go to grid
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Exception $e) {
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // save data in session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
-                // redirect to edit form
-                $this->_redirect('*/*/edit', array('block_id' => $this->getRequest()->getParam('block_id')));
-                return;
-            }
-        }
-        $this->_redirect('*/*/');
-    }
-
-    /**
-     * Delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        // check if we know what should be deleted
-        $id = $this->getRequest()->getParam('block_id');
-        if ($id) {
-            try {
-                // init model and delete
-                $model = $this->_objectManager->create('Magento\Cms\Model\Block');
-                $model->load($id);
-                $model->delete();
-                // display success message
-                $this->messageManager->addSuccess(__('The block has been deleted.'));
-                // go to grid
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Exception $e) {
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // go back to edit form
-                $this->_redirect('*/*/edit', array('block_id' => $id));
-                return;
-            }
-        }
-        // display error message
-        $this->messageManager->addError(__('We can\'t find a block to delete.'));
-        // go to grid
-        $this->_redirect('*/*/');
-    }
-
     /**
      * Check the permission to run it
      *
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/Delete.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..56419a87b79f246e862c2d17cc3480f76b81199c
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/Delete.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+class Delete extends \Magento\Cms\Controller\Adminhtml\Block
+{
+    /**
+     * Delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // check if we know what should be deleted
+        $id = $this->getRequest()->getParam('block_id');
+        if ($id) {
+            try {
+                // init model and delete
+                $model = $this->_objectManager->create('Magento\Cms\Model\Block');
+                $model->load($id);
+                $model->delete();
+                // display success message
+                $this->messageManager->addSuccess(__('The block has been deleted.'));
+                // go to grid
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Exception $e) {
+                // display error message
+                $this->messageManager->addError($e->getMessage());
+                // go back to edit form
+                $this->_redirect('*/*/edit', array('block_id' => $id));
+                return;
+            }
+        }
+        // display error message
+        $this->messageManager->addError(__('We can\'t find a block to delete.'));
+        // go to grid
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/Edit.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..33cbb965633d1bc5b2d45772bb76f9290e4c81f2
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/Edit.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+class Edit extends \Magento\Cms\Controller\Adminhtml\Block
+{
+    /**
+     * Edit CMS block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Blocks'));
+
+        // 1. Get ID and create model
+        $id = $this->getRequest()->getParam('block_id');
+        $model = $this->_objectManager->create('Magento\Cms\Model\Block');
+
+        // 2. Initial checking
+        if ($id) {
+            $model->load($id);
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This block no longer exists.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+        }
+
+        $this->_title->add($model->getId() ? $model->getTitle() : __('New Block'));
+
+        // 3. Set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
+        if (!empty($data)) {
+            $model->setData($data);
+        }
+
+        // 4. Register model to use later in blocks
+        $this->_coreRegistry->register('cms_block', $model);
+
+        // 5. Build edit form
+        $this->_initAction()->_addBreadcrumb(
+            $id ? __('Edit Block') : __('New Block'),
+            $id ? __('Edit Block') : __('New Block')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/Index.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd1b29339bddabcf7ba6df4f8460f4d7d544e7f1
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+class Index extends \Magento\Cms\Controller\Adminhtml\Block
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Blocks'));
+
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/NewAction.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..343a0139230ead08ab17261f943b78025c4ca5bd
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/NewAction.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+class NewAction extends \Magento\Cms\Controller\Adminhtml\Block
+{
+    /**
+     * Create new CMS block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // the same form is used to create and edit
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..84be982f96b8868e9cf9e2cf3f3cf73e610203a5
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/Save.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Block;
+
+class Save extends \Magento\Cms\Controller\Adminhtml\Block
+{
+    /**
+     * Save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // check if data sent
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $id = $this->getRequest()->getParam('block_id');
+            $model = $this->_objectManager->create('Magento\Cms\Model\Block')->load($id);
+            if (!$model->getId() && $id) {
+                $this->messageManager->addError(__('This block no longer exists.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+
+            // init model and set data
+
+            $model->setData($data);
+
+            // try to save it
+            try {
+                // save the data
+                $model->save();
+                // display success message
+                $this->messageManager->addSuccess(__('The block has been saved.'));
+                // clear previously saved data from session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+
+                // check if 'Save and Continue'
+                if ($this->getRequest()->getParam('back')) {
+                    $this->_redirect('*/*/edit', array('block_id' => $model->getId()));
+                    return;
+                }
+                // go to grid
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Exception $e) {
+                // display error message
+                $this->messageManager->addError($e->getMessage());
+                // save data in session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
+                // redirect to edit form
+                $this->_redirect('*/*/edit', array('block_id' => $this->getRequest()->getParam('block_id')));
+                return;
+            }
+        }
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Block/Widget.php b/app/code/Magento/Cms/Controller/Adminhtml/Block/Widget/Chooser.php
similarity index 84%
rename from app/code/Magento/Cms/Controller/Adminhtml/Block/Widget.php
rename to app/code/Magento/Cms/Controller/Adminhtml/Block/Widget/Chooser.php
index ca6804825982d151b2d73746def98a35719648bd..4405eb66e501b688e566dcf36cb251ae694dced1 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Block/Widget.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Block/Widget/Chooser.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Controller\Adminhtml\Block;
+namespace Magento\Cms\Controller\Adminhtml\Block\Widget;
 
-/**
- * Controller for CMS Block Widget plugin
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Widget extends \Magento\Backend\App\Action
+class Chooser extends \Magento\Backend\App\Action
 {
     /**
      * Chooser Source action
      *
      * @return void
      */
-    public function chooserAction()
+    public function execute()
     {
         $uniqId = $this->getRequest()->getParam('uniq_id');
         $pagesGrid = $this->_view->getLayout()->createBlock(
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page.php b/app/code/Magento/Cms/Controller/Adminhtml/Page.php
deleted file mode 100644
index c5c5043a4778a5d7188a48d0f7ebd7f8bf8d8af5..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page.php
+++ /dev/null
@@ -1,314 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Cms\Controller\Adminhtml;
-
-/**
- * Cms manage pages controller
- */
-class Page extends \Magento\Backend\App\Action
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry;
-
-    /**
-     * @var \Magento\Framework\Stdlib\DateTime\Filter\Date
-     */
-    protected $_dateFilter;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\Registry $coreRegistry,
-        \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        $this->_dateFilter = $dateFilter;
-        parent::__construct($context);
-    }
-
-    /**
-     * Init actions
-     *
-     * @return $this
-     */
-    protected function _initAction()
-    {
-        // load layout, set active menu and breadcrumbs
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Cms::cms_page'
-        )->_addBreadcrumb(
-            __('CMS'),
-            __('CMS')
-        )->_addBreadcrumb(
-            __('Manage Pages'),
-            __('Manage Pages')
-        );
-        return $this;
-    }
-
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Pages'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new CMS page
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        // the same form is used to create and edit
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit CMS page
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Pages'));
-
-        // 1. Get ID and create model
-        $pageId = $this->getRequest()->getParam('page_id');
-        $model = $this->_objectManager->create('Magento\Cms\Model\Page');
-
-        // 2. Initial checking
-        if ($pageId) {
-            $model->load($pageId);
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This page no longer exists.'));
-                $this->_redirect('*/*/');
-                return;
-            }
-        }
-
-        $this->_title->add($model->getId() ? $model->getTitle() : __('New Page'));
-
-        // 3. Set entered data if was error when we do save
-        $data = $this->_session->getFormData(true);
-        if (!empty($data)) {
-            $model->setData($data);
-        }
-
-        // 4. Register model to use later in blocks
-        $this->_coreRegistry->register('cms_page', $model);
-
-        // 5. Build edit form
-        $this->_initAction()->_addBreadcrumb(
-            $pageId ? __('Edit Page') : __('New Page'),
-            $pageId ? __('Edit Page') : __('New Page')
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        // check if data sent
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $data = $this->_filterPostData($data);
-            //init model and set data
-            /** @var \Magento\Cms\Model\Page $model */
-            $model = $this->_objectManager->create('Magento\Cms\Model\Page');
-
-            $pageId = $this->getRequest()->getParam('page_id');
-            if ($pageId) {
-                $model->load($pageId);
-            }
-
-            $model->setData($data);
-
-            $this->_eventManager->dispatch(
-                'cms_page_prepare_save',
-                array('page' => $model, 'request' => $this->getRequest())
-            );
-
-            //validating
-            if (!$this->_validatePostData($data)) {
-                $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
-                return;
-            }
-
-            // try to save it
-            try {
-                // save the data
-                $model->save();
-
-                // display success message
-                $this->messageManager->addSuccess(__('The page has been saved.'));
-                // clear previously saved data from session
-                $this->_session->setFormData(false);
-                // check if 'Save and Continue'
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
-                    return;
-                }
-                // go to grid
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong while saving the page.'));
-            }
-
-            $this->_session->setFormData($data);
-            $this->_redirect('*/*/edit', array('page_id' => $this->getRequest()->getParam('page_id')));
-            return;
-        }
-        $this->_redirect('*/*/');
-    }
-
-    /**
-     * Delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        // check if we know what should be deleted
-        $pageId = $this->getRequest()->getParam('page_id');
-        if ($pageId) {
-            $title = '';
-            try {
-                // init model and delete
-                $model = $this->_objectManager->create('Magento\Cms\Model\Page');
-                $model->load($pageId);
-                $title = $model->getTitle();
-                $model->delete();
-                // display success message
-                $this->messageManager->addSuccess(__('The page has been deleted.'));
-                // go to grid
-                $this->_eventManager->dispatch(
-                    'adminhtml_cmspage_on_delete',
-                    array('title' => $title, 'status' => 'success')
-                );
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->_eventManager->dispatch(
-                    'adminhtml_cmspage_on_delete',
-                    array('title' => $title, 'status' => 'fail')
-                );
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // go back to edit form
-                $this->_redirect('*/*/edit', array('page_id' => $pageId));
-                return;
-            }
-        }
-        // display error message
-        $this->messageManager->addError(__('We can\'t find a page to delete.'));
-        // go to grid
-        $this->_redirect('*/*/');
-    }
-
-    /**
-     * Check the permission to run it
-     *
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        switch ($this->getRequest()->getActionName()) {
-            case 'new':
-            case 'save':
-                return $this->_authorization->isAllowed('Magento_Cms::save');
-            case 'delete':
-                return $this->_authorization->isAllowed('Magento_Cms::page_delete');
-            default:
-                return $this->_authorization->isAllowed('Magento_Cms::page');
-        }
-    }
-
-    /**
-     * Filtering posted data. Converting localized data if needed
-     *
-     * @param array $data
-     * @return array
-     */
-    protected function _filterPostData($data)
-    {
-        $inputFilter = new \Zend_Filter_Input(
-            array('custom_theme_from' => $this->_dateFilter, 'custom_theme_to' => $this->_dateFilter),
-            array(),
-            $data
-        );
-        $data = $inputFilter->getUnescaped();
-        return $data;
-    }
-
-    /**
-     * Validate post data
-     *
-     * @param array $data
-     * @return bool     Return FALSE if someone item is invalid
-     */
-    protected function _validatePostData($data)
-    {
-        $errorNo = true;
-        if (!empty($data['layout_update_xml']) || !empty($data['custom_layout_update_xml'])) {
-            /** @var $validatorCustomLayout \Magento\Core\Model\Layout\Update\Validator */
-            $validatorCustomLayout = $this->_objectManager->create('Magento\Core\Model\Layout\Update\Validator');
-            if (!empty($data['layout_update_xml']) && !$validatorCustomLayout->isValid($data['layout_update_xml'])) {
-                $errorNo = false;
-            }
-            if (!empty($data['custom_layout_update_xml'])
-                && !$validatorCustomLayout->isValid($data['custom_layout_update_xml'])
-            ) {
-                $errorNo = false;
-            }
-            foreach ($validatorCustomLayout->getMessages() as $message) {
-                $this->messageManager->addError($message);
-            }
-        }
-        return $errorNo;
-    }
-}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Delete.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4b93801a52cae49121e33322c067d15a4a749d1
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Delete.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+class Delete extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Cms::page_delete');
+    }
+
+    /**
+     * Delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // check if we know what should be deleted
+        $id = $this->getRequest()->getParam('page_id');
+        if ($id) {
+            $title = "";
+            try {
+                // init model and delete
+                $model = $this->_objectManager->create('Magento\Cms\Model\Page');
+                $model->load($id);
+                $title = $model->getTitle();
+                $model->delete();
+                // display success message
+                $this->messageManager->addSuccess(__('The page has been deleted.'));
+                // go to grid
+                $this->_eventManager->dispatch(
+                    'adminhtml_cmspage_on_delete',
+                    array('title' => $title, 'status' => 'success')
+                );
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->_eventManager->dispatch(
+                    'adminhtml_cmspage_on_delete',
+                    array('title' => $title, 'status' => 'fail')
+                );
+                // display error message
+                $this->messageManager->addError($e->getMessage());
+                // go back to edit form
+                $this->_redirect('*/*/edit', array('page_id' => $id));
+                return;
+            }
+        }
+        // display error message
+        $this->messageManager->addError(__('We can\'t find a page to delete.'));
+        // go to grid
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Edit.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6770d7e8e55f4a92e8dc660548758e6d9e21502
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Edit.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+use \Magento\Backend\App\Action;
+
+class Edit extends \Magento\Backend\App\Action
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(Action\Context $context, \Magento\Framework\Registry $registry)
+    {
+        $this->_coreRegistry = $registry;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Cms::save');
+    }
+
+    /**
+     * Init actions
+     *
+     * @return $this
+     */
+    protected function _initAction()
+    {
+        // load layout, set active menu and breadcrumbs
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Cms::cms_page'
+        )->_addBreadcrumb(
+            __('CMS'),
+            __('CMS')
+        )->_addBreadcrumb(
+            __('Manage Pages'),
+            __('Manage Pages')
+        );
+        return $this;
+    }
+
+    /**
+     * Edit CMS page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Pages'));
+
+        // 1. Get ID and create model
+        $id = $this->getRequest()->getParam('page_id');
+        $model = $this->_objectManager->create('Magento\Cms\Model\Page');
+
+        // 2. Initial checking
+        if ($id) {
+            $model->load($id);
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This page no longer exists.'));
+                $this->_redirect('*/*/');
+                return;
+            }
+        }
+
+        $this->_title->add($model->getId() ? $model->getTitle() : __('New Page'));
+
+        // 3. Set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
+        if (!empty($data)) {
+            $model->setData($data);
+        }
+
+        // 4. Register model to use later in blocks
+        $this->_coreRegistry->register('cms_page', $model);
+
+        // 5. Build edit form
+        $this->_initAction()->_addBreadcrumb(
+            $id ? __('Edit Page') : __('New Page'),
+            $id ? __('Edit Page') : __('New Page')
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Index.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e03bd2f7a77c0936606c745dce359ef7c8b86bf
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Index.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * Check the permission to run it
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Cms::page');
+    }
+
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Pages'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Cms::cms_page'
+        )->_addBreadcrumb(
+            __('CMS'),
+            __('CMS')
+        )->_addBreadcrumb(
+            __('Manage Pages'),
+            __('Manage Pages')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/NewAction.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6306c4dd3564348e0de771a48d03305fb7cd1cfb
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/NewAction.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+class NewAction extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Cms::save');
+    }
+
+    /**
+     * Forward to edit
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9a6997654dd4c5dcbc9f18f11d8900ee5441d43
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/PostDataProcessor.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+class PostDataProcessor
+{
+    /**
+     * @var \Magento\Framework\Stdlib\DateTime\Filter\Date
+     */
+    protected $dateFilter;
+
+    /**
+     * @var \Magento\Core\Model\Layout\Update\ValidatorFactory
+     */
+    protected $validatorFactory;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @param \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter
+     * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     * @param \Magento\Core\Model\Layout\Update\ValidatorFactory $validatorFactory
+     */
+    public function __construct(
+        \Magento\Framework\Stdlib\DateTime\Filter\Date $dateFilter,
+        \Magento\Framework\Message\ManagerInterface $messageManager,
+        \Magento\Core\Model\Layout\Update\ValidatorFactory $validatorFactory
+    ) {
+        $this->dateFilter = $dateFilter;
+        $this->messageManager = $messageManager;
+        $this->validatorFactory = $validatorFactory;
+    }
+
+    /**
+     * Filtering posted data. Converting localized data if needed
+     *
+     * @param array $data
+     * @return array
+     */
+    public function filter($data)
+    {
+        $inputFilter = new \Zend_Filter_Input(
+            array('custom_theme_from' => $this->dateFilter, 'custom_theme_to' => $this->dateFilter),
+            array(),
+            $data
+        );
+        $data = $inputFilter->getUnescaped();
+        return $data;
+    }
+
+    /**
+     * Validate post data
+     *
+     * @param array $data
+     * @return bool     Return FALSE if someone item is invalid
+     */
+    public function validate($data)
+    {
+        $errorNo = true;
+        if (!empty($data['layout_update_xml']) || !empty($data['custom_layout_update_xml'])) {
+            /** @var $validatorCustomLayout \Magento\Core\Model\Layout\Update\Validator */
+            $validatorCustomLayout = $this->validatorFactory->create();
+            if (!empty($data['layout_update_xml']) && !$validatorCustomLayout->isValid($data['layout_update_xml'])) {
+                $errorNo = false;
+            }
+            if (!empty($data['custom_layout_update_xml'])
+                && !$validatorCustomLayout->isValid($data['custom_layout_update_xml'])
+            ) {
+                $errorNo = false;
+            }
+            foreach ($validatorCustomLayout->getMessages() as $message) {
+                $this->messageManager->addError($message);
+            }
+        }
+        return $errorNo;
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6cd640cb636d6756b614f11319ee954528b7e34
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Save.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Page;
+
+use Magento\Backend\App\Action;
+
+class Save extends \Magento\Backend\App\Action
+{
+    /**
+     * @var PostDataProcessor
+     */
+    protected $dataProcessor;
+
+    /**
+     * @param Action\Context $context
+     * @param PostDataProcessor $dataProcessor
+     */
+    public function __construct(Action\Context $context, PostDataProcessor $dataProcessor)
+    {
+        $this->dataProcessor = $dataProcessor;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Cms::save');
+    }
+
+    /**
+     * Save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // check if data sent
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $data = $this->dataProcessor->filter($data);
+            //init model and set data
+            $model = $this->_objectManager->create('Magento\Cms\Model\Page');
+
+            $id = $this->getRequest()->getParam('page_id');
+            if ($id) {
+                $model->load($id);
+            }
+
+            $model->setData($data);
+
+            $this->_eventManager->dispatch(
+                'cms_page_prepare_save',
+                array('page' => $model, 'request' => $this->getRequest())
+            );
+
+            //validating
+            if (!$this->dataProcessor->validate($data)) {
+                $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
+                return;
+            }
+
+            // try to save it
+            try {
+                // save the data
+                $model->save();
+
+                // display success message
+                $this->messageManager->addSuccess(__('The page has been saved.'));
+                // clear previously saved data from session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+                // check if 'Save and Continue'
+                if ($this->getRequest()->getParam('back')) {
+                    $this->_redirect('*/*/edit', array('page_id' => $model->getId(), '_current' => true));
+                    return;
+                }
+                // go to grid
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong while saving the page.'));
+            }
+
+            $this->_getSession()->setFormData($data);
+            $this->_redirect('*/*/edit', array('page_id' => $this->getRequest()->getParam('page_id')));
+            return;
+        }
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Page/Widget.php b/app/code/Magento/Cms/Controller/Adminhtml/Page/Widget/Chooser.php
similarity index 84%
rename from app/code/Magento/Cms/Controller/Adminhtml/Page/Widget.php
rename to app/code/Magento/Cms/Controller/Adminhtml/Page/Widget/Chooser.php
index 2067e9a5dbebb487cf2bfba313c1e17b5b2913c5..02ac342661397c43f181cdb32f421c2a413f4b63 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Page/Widget.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Page/Widget/Chooser.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Controller\Adminhtml\Page;
+namespace Magento\Cms\Controller\Adminhtml\Page\Widget;
 
-/**
- * Controller for CMS Page Link Widget plugin
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Widget extends \Magento\Backend\App\Action
+class Chooser extends \Magento\Backend\App\Action
 {
     /**
      * Chooser Source action
      *
      * @return void
      */
-    public function chooserAction()
+    public function execute()
     {
         $uniqId = $this->getRequest()->getParam('uniq_id');
         $pagesGrid = $this->_view->getLayout()->createBlock(
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
similarity index 89%
rename from app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg.php
rename to app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
index 8961f6a4c9aff6b9c5be9f0548cc5f2e21763420..09cd1d3d18a95d20be1c72e5206a4e3c3765faaf 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Directive.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Controller\Adminhtml;
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg;
 
-/**
- * Wysiwyg controller for different purposes
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Wysiwyg extends \Magento\Backend\App\Action
+class Directive extends \Magento\Backend\App\Action
 {
     /**
      * Template directives callback
@@ -37,7 +33,7 @@ class Wysiwyg extends \Magento\Backend\App\Action
      *
      * @return void
      */
-    public function directiveAction()
+    public function execute()
     {
         $directive = $this->getRequest()->getParam('___directive');
         $directive = $this->_objectManager->get('Magento\Core\Helper\Data')->urlDecode($directive);
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php
index c572f8794fbffa1b24c3d54a183783a01961eca7..9887ec09ca48384360fd82168bdf737518bcab5a 100644
--- a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images.php
@@ -58,202 +58,6 @@ class Images extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store');
-
-        try {
-            $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->getCurrentPath();
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        }
-        $this->_initAction();
-        $this->_view->loadLayout('overlay_popup');
-        $block = $this->_view->getLayout()->getBlock('wysiwyg_images.js');
-        if ($block) {
-            $block->setStoreId($storeId);
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Tree json action
-     *
-     * @return void
-     */
-    public function treeJsonAction()
-    {
-        try {
-            $this->_initAction();
-            $this->getResponse()->representJson(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Tree'
-                )->getTreeJson()
-            );
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Contents action
-     *
-     * @return void
-     */
-    public function contentsAction()
-    {
-        try {
-            $this->_initAction()->_saveSessionCurrentPath();
-            $this->_view->loadLayout('empty');
-            $this->_view->renderLayout();
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * New folder action
-     *
-     * @return void
-     */
-    public function newFolderAction()
-    {
-        try {
-            $this->_initAction();
-            $name = $this->getRequest()->getPost('name');
-            $path = $this->getStorage()->getSession()->getCurrentPath();
-            $result = $this->getStorage()->createDirectory($name, $path);
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Delete folder action
-     *
-     * @return void
-     */
-    public function deleteFolderAction()
-    {
-        try {
-            $path = $this->getStorage()->getCmsWysiwygImages()->getCurrentPath();
-            $this->getStorage()->deleteDirectory($path);
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Delete file from media storage
-     *
-     * @return void
-     */
-    public function deleteFilesAction()
-    {
-        try {
-            if (!$this->getRequest()->isPost()) {
-                throw new \Exception('Wrong request.');
-            }
-            $files = $this->getRequest()->getParam('files');
-
-            /** @var $helper \Magento\Cms\Helper\Wysiwyg\Images */
-            $helper = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images');
-            $path = $this->getStorage()->getSession()->getCurrentPath();
-            foreach ($files as $file) {
-                $file = $helper->idDecode($file);
-                /** @var \Magento\Framework\App\Filesystem $filesystem */
-                $filesystem = $this->_objectManager->get('Magento\Framework\App\Filesystem');
-                $dir = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MEDIA_DIR);
-                $filePath = $path . '/' . $file;
-                if ($dir->isFile($dir->getRelativePath($filePath))) {
-                    $this->getStorage()->deleteFile($filePath);
-                }
-            }
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Files upload processing
-     *
-     * @return void
-     */
-    public function uploadAction()
-    {
-        try {
-            $this->_initAction();
-            $targetPath = $this->getStorage()->getSession()->getCurrentPath();
-            $result = $this->getStorage()->uploadFile($targetPath, $this->getRequest()->getParam('type'));
-        } catch (\Exception $e) {
-            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Fire when select image
-     *
-     * @return void
-     */
-    public function onInsertAction()
-    {
-        $helper = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images');
-        $storeId = $this->getRequest()->getParam('store');
-
-        $filename = $this->getRequest()->getParam('filename');
-        $filename = $helper->idDecode($filename);
-        $asIs = $this->getRequest()->getParam('as_is');
-
-        $this->_objectManager->get('Magento\Catalog\Helper\Data')->setStoreId($storeId);
-        $helper->setStoreId($storeId);
-
-        $image = $helper->getImageHtmlDeclaration($filename, $asIs);
-        $this->getResponse()->setBody($image);
-    }
-
-    /**
-     * Generate image thumbnail on the fly
-     *
-     * @return void
-     */
-    public function thumbnailAction()
-    {
-        $file = $this->getRequest()->getParam('file');
-        $file = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->idDecode($file);
-        $thumb = $this->getStorage()->resizeOnTheFly($file);
-        if ($thumb !== false) {
-            /** @var \Magento\Framework\Image\Adapter\AdapterInterface $image */
-            $image = $this->_objectManager->get('Magento\Framework\Image\AdapterFactory')->create();
-            $image->open($thumb);
-            $this->getResponse()->setHeader('Content-Type', $image->getMimeType())->setBody($image->getImage());
-        } else {
-            // todo: generate some placeholder
-        }
-    }
-
     /**
      * Register storage model and return it
      *
@@ -268,19 +72,6 @@ class Images extends \Magento\Backend\App\Action
         return $this->_coreRegistry->registry('storage');
     }
 
-    /**
-     * Save current path in session
-     *
-     * @return $this
-     */
-    protected function _saveSessionCurrentPath()
-    {
-        $this->getStorage()->getSession()->setCurrentPath(
-            $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->getCurrentPath()
-        );
-        return $this;
-    }
-
     /**
      * Check current user permission on resource and privilege
      *
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Contents.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Contents.php
new file mode 100644
index 0000000000000000000000000000000000000000..94d41ac67112c502ce9b74f504a58516dc6814a0
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Contents.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class Contents extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Save current path in session
+     *
+     * @return $this
+     */
+    protected function _saveSessionCurrentPath()
+    {
+        $this->getStorage()->getSession()->setCurrentPath(
+            $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->getCurrentPath()
+        );
+        return $this;
+    }
+
+    /**
+     * Contents action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initAction()->_saveSessionCurrentPath();
+            $this->_view->loadLayout('empty');
+            $this->_view->renderLayout();
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6751601562728143bc2a2c905f040c64c9edcf6
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFiles.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class DeleteFiles extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Delete file from media storage
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            if (!$this->getRequest()->isPost()) {
+                throw new \Exception('Wrong request.');
+            }
+            $files = $this->getRequest()->getParam('files');
+
+            /** @var $helper \Magento\Cms\Helper\Wysiwyg\Images */
+            $helper = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images');
+            $path = $this->getStorage()->getSession()->getCurrentPath();
+            foreach ($files as $file) {
+                $file = $helper->idDecode($file);
+                /** @var \Magento\Framework\App\Filesystem $filesystem */
+                $filesystem = $this->_objectManager->get('Magento\Framework\App\Filesystem');
+                $dir = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MEDIA_DIR);
+                $filePath = $path . '/' . $file;
+                if ($dir->isFile($dir->getRelativePath($filePath))) {
+                    $this->getStorage()->deleteFile($filePath);
+                }
+            }
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFolder.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..65e19d65448c6d488bcbfd6eff1eb110ae893592
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/DeleteFolder.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class DeleteFolder extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Delete folder action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $path = $this->getStorage()->getCmsWysiwygImages()->getCurrentPath();
+            $this->getStorage()->deleteDirectory($path);
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Index.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..217bedbe0c750c64c11fc55e4c3d4e0721764f02
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Index.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class Index extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store');
+
+        try {
+            $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->getCurrentPath();
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        }
+        $this->_initAction();
+        $this->_view->loadLayout('overlay_popup');
+        $block = $this->_view->getLayout()->getBlock('wysiwyg_images.js');
+        if ($block) {
+            $block->setStoreId($storeId);
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/NewFolder.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/NewFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..13a19007a11383b4c37a106c65af8aaaf8aefd96
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/NewFolder.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class NewFolder extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * New folder action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initAction();
+            $name = $this->getRequest()->getPost('name');
+            $path = $this->getStorage()->getSession()->getCurrentPath();
+            $result = $this->getStorage()->createDirectory($name, $path);
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/OnInsert.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/OnInsert.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b884a33ab74d281f93dab7b8f42330dd8e20c2c
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/OnInsert.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class OnInsert extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Fire when select image
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $helper = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images');
+        $storeId = $this->getRequest()->getParam('store');
+
+        $filename = $this->getRequest()->getParam('filename');
+        $filename = $helper->idDecode($filename);
+        $asIs = $this->getRequest()->getParam('as_is');
+
+        $this->_objectManager->get('Magento\Catalog\Helper\Data')->setStoreId($storeId);
+        $helper->setStoreId($storeId);
+
+        $image = $helper->getImageHtmlDeclaration($filename, $asIs);
+        $this->getResponse()->setBody($image);
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Thumbnail.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Thumbnail.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0738452bf46629b068f0b65092fad54f582677e
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Thumbnail.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class Thumbnail extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Generate image thumbnail on the fly
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $file = $this->getRequest()->getParam('file');
+        $file = $this->_objectManager->get('Magento\Cms\Helper\Wysiwyg\Images')->idDecode($file);
+        $thumb = $this->getStorage()->resizeOnTheFly($file);
+        if ($thumb !== false) {
+            /** @var \Magento\Framework\Image\Adapter\AdapterInterface $image */
+            $image = $this->_objectManager->get('Magento\Framework\Image\AdapterFactory')->create();
+            $image->open($thumb);
+            $this->getResponse()->setHeader('Content-Type', $image->getMimeType())->setBody($image->getImage());
+        } else {
+            // todo: generate some placeholder
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/TreeJson.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/TreeJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..d18ddb65f8c6722ccbbabc78c6103e7039e023c5
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/TreeJson.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class TreeJson extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Tree json action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initAction();
+            $this->getResponse()->representJson(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\Cms\Block\Adminhtml\Wysiwyg\Images\Tree'
+                )->getTreeJson()
+            );
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Upload.php b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..999e55d93947c4b1cdb21ad9b5edb30daf53d84d
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Adminhtml/Wysiwyg/Images/Upload.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Adminhtml\Wysiwyg\Images;
+
+class Upload extends \Magento\Cms\Controller\Adminhtml\Wysiwyg\Images
+{
+    /**
+     * Files upload processing
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initAction();
+            $targetPath = $this->getStorage()->getSession()->getCurrentPath();
+            $result = $this->getStorage()->uploadFile($targetPath, $this->getRequest()->getParam('type'));
+        } catch (\Exception $e) {
+            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Index.php b/app/code/Magento/Cms/Controller/Index.php
deleted file mode 100644
index b7f1898b28597c5806fb61237110a0676216d139..0000000000000000000000000000000000000000
--- a/app/code/Magento/Cms/Controller/Index.php
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Cms\Controller;
-
-/**
- * Cms index controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Index extends \Magento\Framework\App\Action\Action
-{
-    /**
-     * Renders CMS Home page
-     *
-     * @param string|null $coreRoute
-     * @return void
-     */
-    public function indexAction($coreRoute = null)
-    {
-        $pageId = $this->_objectManager->get(
-            'Magento\Framework\App\Config\ScopeConfigInterface'
-        )->getValue(
-            \Magento\Cms\Helper\Page::XML_PATH_HOME_PAGE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        if (!$this->_objectManager->get('Magento\Cms\Helper\Page')->renderPage($this, $pageId)) {
-            $this->_forward('defaultIndex');
-        }
-    }
-
-    /**
-     * Default index action (with 404 Not Found headers)
-     * Used if default page don't configure or available
-     *
-     * @return void
-     */
-    public function defaultIndexAction()
-    {
-        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
-        $this->getResponse()->setHeader('Status', '404 File not found');
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Default no route page action
-     * Used if no route page don't configure or available
-     *
-     * @return void
-     */
-    public function defaultNoRouteAction()
-    {
-        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
-        $this->getResponse()->setHeader('Status', '404 File not found');
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Render Disable cookies page
-     *
-     * @return void
-     */
-    public function noCookiesAction()
-    {
-        $pageId = $this->_objectManager->get(
-            'Magento\Framework\App\Config\ScopeConfigInterface',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        )->getValue(
-            \Magento\Cms\Helper\Page::XML_PATH_NO_COOKIES_PAGE,
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        );
-        if (!$this->_objectManager->get('Magento\Cms\Helper\Page')->renderPage($this, $pageId)) {
-            $this->_forward('defaultNoCookies');
-        }
-    }
-
-    /**
-     * Default no cookies page action
-     * Used if no cookies page don't configure or available
-     *
-     * @return void
-     */
-    public function defaultNoCookiesAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-}
diff --git a/app/code/Magento/Cms/Controller/Index/DefaultIndex.php b/app/code/Magento/Cms/Controller/Index/DefaultIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..242035eb3e112dd46e12582cc865f507271e524b
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Index/DefaultIndex.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ * Default index action (with 404 Not Found headers)
+ * Used if default page don't configure or available
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Index;
+
+class DefaultIndex extends DefaultNoRoute
+{
+}
diff --git a/app/code/Magento/Cms/Controller/Index/DefaultNoCookies.php b/app/code/Magento/Cms/Controller/Index/DefaultNoCookies.php
new file mode 100644
index 0000000000000000000000000000000000000000..cfaccac7202eaa4e024e6dfe1ee2c8fcc6758e81
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Index/DefaultNoCookies.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Index;
+
+class DefaultNoCookies extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Default no cookies page action
+     * Used if no cookies page don't configure or available
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Index/DefaultNoRoute.php b/app/code/Magento/Cms/Controller/Index/DefaultNoRoute.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca90def816df4ff56ccb677882a97271b825bcd6
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Index/DefaultNoRoute.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Default no route page action
+ * Used if no route page don't configure or available
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Index;
+
+class DefaultNoRoute extends \Magento\Framework\App\Action\Action
+{
+    /**
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
+        $this->getResponse()->setHeader('Status', '404 File not found');
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Index/Index.php b/app/code/Magento/Cms/Controller/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..8318763b318f0fd6fc0651619032279fb71792d2
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Index/Index.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Index;
+
+class Index extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Renders CMS Home page
+     *
+     * @param string|null $coreRoute
+     * @return void
+     */
+    public function execute($coreRoute = null)
+    {
+        $pageId = $this->_objectManager->get(
+            'Magento\Framework\App\Config\ScopeConfigInterface'
+        )->getValue(
+            \Magento\Cms\Helper\Page::XML_PATH_HOME_PAGE,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+        if (!$this->_objectManager->get('Magento\Cms\Helper\Page')->renderPage($this, $pageId)) {
+            $this->_forward('defaultIndex');
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Index/NoCookies.php b/app/code/Magento/Cms/Controller/Index/NoCookies.php
new file mode 100644
index 0000000000000000000000000000000000000000..e716296088718da91ddbf7e7906756fe7bacc485
--- /dev/null
+++ b/app/code/Magento/Cms/Controller/Index/NoCookies.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Cms\Controller\Index;
+
+class NoCookies extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Render Disable cookies page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $pageId = $this->_objectManager->get(
+            'Magento\Framework\App\Config\ScopeConfigInterface',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        )->getValue(
+            \Magento\Cms\Helper\Page::XML_PATH_NO_COOKIES_PAGE,
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+        );
+        if (!$this->_objectManager->get('Magento\Cms\Helper\Page')->renderPage($this, $pageId)) {
+            $this->_forward('defaultNoCookies');
+        }
+    }
+}
diff --git a/app/code/Magento/Cms/Controller/Noroute.php b/app/code/Magento/Cms/Controller/Noroute/Index.php
similarity index 92%
rename from app/code/Magento/Cms/Controller/Noroute.php
rename to app/code/Magento/Cms/Controller/Noroute/Index.php
index 0a0abd31b6a580e11a381efb9628479fa20ebfa3..7d2f60a4c808de84dd62f4b311659a21360339bc 100644
--- a/app/code/Magento/Cms/Controller/Noroute.php
+++ b/app/code/Magento/Cms/Controller/Noroute/Index.php
@@ -22,16 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Controller;
+namespace Magento\Cms\Controller\Noroute;
 
-class Noroute extends \Magento\Framework\App\Action\Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * Render CMS 404 Not found page
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
         $this->getResponse()->setHeader('Status', '404 File not found');
diff --git a/app/code/Magento/Cms/Controller/Page.php b/app/code/Magento/Cms/Controller/Page/View.php
similarity index 85%
rename from app/code/Magento/Cms/Controller/Page.php
rename to app/code/Magento/Cms/Controller/Page/View.php
index 47ad39c81693f435d0ffdbd20b49bc4200046fa0..85ff06a615abb1527d929da0efe9011accec8d61 100644
--- a/app/code/Magento/Cms/Controller/Page.php
+++ b/app/code/Magento/Cms/Controller/Page/View.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Cms\Controller;
+namespace Magento\Cms\Controller\Page;
 
-/**
- * CMS Page controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Page extends \Magento\Framework\App\Action\Action
+class View extends \Magento\Framework\App\Action\Action
 {
     /**
      * View CMS page action
      *
      * @return void
      */
-    public function viewAction()
+    public function execute()
     {
         $pageId = $this->getRequest()->getParam('page_id', $this->getRequest()->getParam('id', false));
         if (!$this->_objectManager->get('Magento\Cms\Helper\Page')->renderPage($this, $pageId)) {
diff --git a/app/code/Magento/Cms/Controller/Router.php b/app/code/Magento/Cms/Controller/Router.php
index c81962aaa887b5feef5112081bd5b722b99e3db0..a2f2f53527b03f9abcaad85bc51789ed5ee7efa3 100644
--- a/app/code/Magento/Cms/Controller/Router.php
+++ b/app/code/Magento/Cms/Controller/Router.php
@@ -28,8 +28,13 @@ namespace Magento\Cms\Controller;
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-class Router extends \Magento\Framework\App\Router\AbstractRouter
+class Router implements \Magento\Framework\App\RouterInterface
 {
+    /**
+     * @var \Magento\Framework\App\ActionFactory
+     */
+    protected $actionFactory;
+
     /**
      * Event manager
      *
@@ -73,8 +78,6 @@ class Router extends \Magento\Framework\App\Router\AbstractRouter
     protected $_response;
 
     /**
-     * Construct
-     *
      * @param \Magento\Framework\App\ActionFactory $actionFactory
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
      * @param \Magento\Framework\UrlInterface $url
@@ -92,7 +95,7 @@ class Router extends \Magento\Framework\App\Router\AbstractRouter
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\App\ResponseInterface $response
     ) {
-        parent::__construct($actionFactory);
+        $this->actionFactory = $actionFactory;
         $this->_eventManager = $eventManager;
         $this->_url = $url;
         $this->_appState = $appState;
@@ -128,7 +131,7 @@ class Router extends \Magento\Framework\App\Router\AbstractRouter
         if ($condition->getRedirectUrl()) {
             $this->_response->setRedirect($condition->getRedirectUrl());
             $request->setDispatched(true);
-            return $this->_actionFactory->createController(
+            return $this->actionFactory->create(
                 'Magento\Framework\App\Action\Redirect',
                 array('request' => $request)
             );
@@ -148,7 +151,7 @@ class Router extends \Magento\Framework\App\Router\AbstractRouter
         $request->setModuleName('cms')->setControllerName('page')->setActionName('view')->setParam('page_id', $pageId);
         $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $identifier);
 
-        return $this->_actionFactory->createController(
+        return $this->actionFactory->create(
             'Magento\Framework\App\Action\Forward',
             array('request' => $request)
         );
diff --git a/app/code/Magento/Cms/etc/adminhtml/routes.xml b/app/code/Magento/Cms/etc/adminhtml/routes.xml
index f69daf2ea0fce7f7a21fe4b677e2e698f83e7b11..bed66155a0931906618a38eb233c9d29a725cbcb 100644
--- a/app/code/Magento/Cms/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Cms/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="cms" frontName="cms">
-            <module name="Magento_Cms_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_Cms" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelector.php b/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelector.php
index dfad09a2c0159850e131acefd3db735acdbb5d72..e8de9a738b56708d31b175f0ff81c1a4dffea274 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelector.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelector.php
@@ -48,7 +48,7 @@ class AttributeSelector extends \Magento\Backend\Block\Template
     public function getSuggestWidgetOptions()
     {
         return array(
-            'source' => $this->getUrl('*/product_attribute_suggestConfigurableAttributes'),
+            'source' => $this->getUrl('*/product_attribute/suggestConfigurableAttributes'),
             'minLength' => 0,
             'className' => 'category-select',
             'showAll' => true
diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
index 17ac2f7bb676700f187e0d712d34b4021969c308..7e83d31d35c4cc42992a859e846ec46cd5134f15 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
@@ -25,6 +25,8 @@
  */
 namespace Magento\ConfigurableProduct\Block\Product\View\Type;
 
+use Magento\Customer\Helper\Session\CurrentCustomer;
+
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
@@ -37,6 +39,13 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView
      */
     protected $catalogProduct = null;
 
+    /**
+     * Current customer
+     *
+     * @var CurrentCustomer
+     */
+    protected $currentCustomer;
+
     /**
      * Prices
      *
@@ -60,6 +69,7 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView
      * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
      * @param \Magento\ConfigurableProduct\Helper\Data $helper
      * @param \Magento\Catalog\Helper\Product $catalogProduct
+     * @param CurrentCustomer $currentCustomer
      * @param array $data
      */
     public function __construct(
@@ -68,11 +78,13 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView
         \Magento\Framework\Json\EncoderInterface $jsonEncoder,
         \Magento\ConfigurableProduct\Helper\Data $helper,
         \Magento\Catalog\Helper\Product $catalogProduct,
+        CurrentCustomer $currentCustomer,
         array $data = array()
     ) {
         $this->helper = $helper;
         $this->jsonEncoder = $jsonEncoder;
         $this->catalogProduct = $catalogProduct;
+        $this->currentCustomer = $currentCustomer;
         parent::__construct(
             $context,
             $arrayUtils,
@@ -176,7 +188,7 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView
             'oldPrice' => $this->_registerJsPrice($this->_convertPrice($currentProduct->getPrice())),
             'productId' => $currentProduct->getId(),
             'chooseText' => __('Choose an Option...'),
-            'taxConfig' => $attributePrice->getTaxConfig(),
+            'taxConfig' => $attributePrice->getTaxConfig($this->currentCustomer->getCustomerId()),
             'images' => $options['images'],
             'baseImage' => $options['baseImage']
         );
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/AddAttribute.php
similarity index 93%
rename from app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product.php
rename to app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/AddAttribute.php
index 4678b757aa8cb238d2c90c84446f3772e69500a8..d6d51024096a58b175c3001536ec35998ccf1479 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/AddAttribute.php
@@ -22,11 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\ConfigurableProduct\Controller\Adminhtml;
+namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product;
 
 use Magento\Backend\App\Action;
 
-class Product extends Action
+class AddAttribute extends Action
 {
     /**
      * @var \Magento\Catalog\Controller\Adminhtml\Product\Builder
@@ -50,7 +50,7 @@ class Product extends Action
      *
      * @return void
      */
-    public function addAttributeAction()
+    public function execute()
     {
         $this->_view->loadLayout('popup');
         $this->productBuilder->build($this->getRequest());
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php
index e6f5549ad2f7680583ef59c84a5b0ed96bd72167..a03b2afd35ce4721ef137696c6e3cd17238be588 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributes.php
@@ -69,7 +69,7 @@ class SuggestConfigurableAttributes extends Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->getResponse()->representJson(
             $this->coreHelper->jsonEncode(
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations/Index.php
similarity index 98%
rename from app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations.php
rename to app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations/Index.php
index 2a824de4b0253646044082f8cc218ff214199b5a..0a8c584902a0e5010f65e30d7db28cef8c88a9b6 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/GenerateVariations/Index.php
@@ -22,13 +22,13 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product;
+namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\GenerateVariations;
 
 use Magento\Backend\App\Action;
 use Magento\Catalog\Controller\Adminhtml\Product;
 use Magento\Catalog\Model\Resource\Eav\AttributeFactory;
 
-class GenerateVariations extends Action
+class Index extends Action
 {
     /**
      * @var Product\Initialization\Helper
@@ -73,20 +73,6 @@ class GenerateVariations extends Action
         return $this->_authorization->isAllowed('Magento_Catalog::products');
     }
 
-    /**
-     * Generate product variations matrix
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_saveAttributeOptions();
-        $this->getRequest()->setParam('variations-matrix', array());
-        $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
     /**
      * Save attribute options just created by user
      *
@@ -136,4 +122,18 @@ class GenerateVariations extends Action
 
         $this->getRequest()->setParam('product', $productData);
     }
+
+    /**
+     * Generate product variations matrix
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_saveAttributeOptions();
+        $this->getRequest()->setParam('variations-matrix', array());
+        $this->initializationHelper->initialize($this->productBuilder->build($this->getRequest()));
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php
similarity index 94%
rename from app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig.php
rename to app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php
index a02eb06cd2fd2cd49229a8958fd31eefd9fba19b..e9da15ec75df533d2675786a9b23197874bcbd8a 100644
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig.php
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Super config product controller
  *
  * Magento
  *
@@ -23,12 +22,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product;
+namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\SuperConfig;
 
 use Magento\Backend\App\Action;
 use Magento\Catalog\Controller\Adminhtml\Product;
 
-class SuperConfig extends Action
+class Index extends Action
 {
     /**
      * @var \Magento\Catalog\Controller\Adminhtml\Product\Builder
@@ -48,7 +47,7 @@ class SuperConfig extends Action
     /**
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->productBuilder->build($this->getRequest());
         $this->_view->loadLayout(false);
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/AttributePrice.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/AttributePrice.php
index 607b4aef3af19cef70d73af3ce97cf837a1a12a2..fd87bf057ad9c077f0b082d3cbce2c338bea0e97 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/AttributePrice.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/AttributePrice.php
@@ -276,11 +276,12 @@ class AttributePrice extends AbstractPrice implements AttributePriceInterface
     /**
      * Returns tax config for Configurable options
      *
+     * @param int|null $customerId
      * @return array
      */
-    public function getTaxConfig()
+    public function getTaxConfig($customerId)
     {
-        $config = $this->prepareAdjustmentConfig();
+        $config = $this->prepareAdjustmentConfig($customerId);
         unset($config['product']);
         return $config;
     }
@@ -288,10 +289,12 @@ class AttributePrice extends AbstractPrice implements AttributePriceInterface
     /**
      * Default values for configurable options
      *
+     * @param int|null $customerId
      * @return array
      */
-    public function prepareAdjustmentConfig()
+    public function prepareAdjustmentConfig($customerId)
     {
+        //pass customer
         return [
             'includeTax' => false,
             'showIncludeTax' => false,
@@ -299,7 +302,8 @@ class AttributePrice extends AbstractPrice implements AttributePriceInterface
             'defaultTax' => 0,
             'currentTax' => 0,
             'inclTaxTitle' => __('Incl. Tax'),
-            'product' => $this->product
+            'product' => $this->product,
+            'customerId' => $customerId
         ];
     }
 
diff --git a/app/code/Magento/Connect/Block/Adminhtml/Extension/Custom/Edit.php b/app/code/Magento/Connect/Block/Adminhtml/Extension/Custom/Edit.php
index 8b058d7d08ecfa027ff5c23cd44cf98f8efaf3ca..812cb85cd7315fe2542f911f53c2ea4450671545 100644
--- a/app/code/Magento/Connect/Block/Adminhtml/Extension/Custom/Edit.php
+++ b/app/code/Magento/Connect/Block/Adminhtml/Extension/Custom/Edit.php
@@ -46,10 +46,10 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('back');
-        $this->_updateButton('reset', 'onclick', "resetPackage()");
+        $this->buttonList->remove('back');
+        $this->buttonList->update('reset', 'onclick', "resetPackage()");
 
-        $this->_addButton(
+        $this->buttonList->add(
             'create',
             array(
                 'label' => __('Save Data and Create Package'),
@@ -60,7 +60,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                 )
             )
         );
-        $this->_addButton(
+        $this->buttonList->add(
             'save_as',
             array(
                 'label' => __('Save As...'),
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom.php
index c1f10c432ff2205a83c9479cced8905004a03cf2..247467f99edc794c2bdf1360f28986da5dff6751 100644
--- a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom.php
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom.php
@@ -31,165 +31,6 @@ namespace Magento\Connect\Controller\Adminhtml\Extension;
 
 class Custom extends \Magento\Backend\App\Action
 {
-    /**
-     * Redirect to edit Extension Package action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Package Extensions'));
-
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit Extension Package Form
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Extension'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Connect::system_extensions_custom');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Reset Extension Package form data
-     *
-     * @return void
-     */
-    public function resetAction()
-    {
-        $this->_objectManager->get('Magento\Connect\Model\Session')->unsCustomExtensionPackageFormData();
-        $this->_redirect('adminhtml/*/edit');
-    }
-
-    /**
-     * Load Local Extension Package
-     *
-     * @return void
-     */
-    public function loadAction()
-    {
-        $packageName = base64_decode(strtr($this->getRequest()->getParam('id'), '-_,', '+/='));
-        if ($packageName) {
-            $session = $this->_objectManager->get('Magento\Connect\Model\Session');
-            try {
-                $data = $this->_objectManager->get('Magento\Connect\Helper\Data')->loadLocalPackage($packageName);
-                if (!$data) {
-                    throw new \Magento\Framework\Model\Exception(__('Something went wrong loading the package data.'));
-                }
-                $data = array_merge($data, array('file_name' => $packageName));
-                $session->setCustomExtensionPackageFormData($data);
-                $this->messageManager->addSuccess(__('The package %1 data has been loaded.', $packageName));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-        $this->_redirect('adminhtml/*/edit');
-    }
-
-    /**
-     * Save Extension Package
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $session = $this->_objectManager->get('Magento\Connect\Model\Session');
-        $p = $this->getRequest()->getPost();
-
-        if (!empty($p['_create'])) {
-            $create = true;
-            unset($p['_create']);
-        }
-
-        if ($p['file_name'] == '') {
-            $p['file_name'] = $p['name'];
-        }
-
-        $session->setCustomExtensionPackageFormData($p);
-        try {
-            $ext = $this->_objectManager->create('Magento\Connect\Model\Extension');
-            /** @var $ext \Magento\Connect\Model\Extension */
-            $ext->setData($p);
-            if ($ext->savePackage()) {
-                $this->messageManager->addSuccess(__('The package data has been saved.'));
-            } else {
-                $this->messageManager->addError(__('Something went wrong saving the package data.'));
-                $this->_redirect('adminhtml/*/edit');
-            }
-            if (empty($create)) {
-                $this->_redirect('adminhtml/*/edit');
-            } else {
-                $this->_forward('create');
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('adminhtml/*');
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Something went wrong saving the package.'));
-            $this->_redirect('adminhtml/*');
-        }
-    }
-
-    /**
-     * Create new Extension Package
-     *
-     * @return void
-     */
-    public function createAction()
-    {
-        $session = $this->_objectManager->get('Magento\Connect\Model\Session');
-        try {
-            $post = $this->getRequest()->getPost();
-            $session->setCustomExtensionPackageFormData($post);
-            $ext = $this->_objectManager->create('Magento\Connect\Model\Extension');
-            $ext->setData($post);
-            $packageVersion = $this->getRequest()->getPost('version_ids');
-            if (is_array($packageVersion)) {
-                if (in_array(\Magento\Framework\Connect\Package::PACKAGE_VERSION_2X, $packageVersion)) {
-                    $ext->createPackage();
-                }
-                if (in_array(\Magento\Framework\Connect\Package::PACKAGE_VERSION_1X, $packageVersion)) {
-                    $ext->createPackageV1x();
-                }
-            }
-            $this->_redirect('adminhtml/*');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('adminhtml/*');
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Something went wrong creating the package.'));
-            $this->_redirect('adminhtml/*');
-        }
-    }
-
-    /**
-     * Load Grid with Local Packages
-     *
-     * @return void
-     */
-    public function loadtabAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Grid for loading packages
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
 
     /**
      * Check is allowed access to actions
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Create.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Create.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd62813b0b64410dc40dfdd3ec40c7d5ff4b6852
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Create.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Create extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Create new Extension Package
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Connect\Model\Session');
+        try {
+            $post = $this->getRequest()->getPost();
+            $session->setCustomExtensionPackageFormData($post);
+            $ext = $this->_objectManager->create('Magento\Connect\Model\Extension');
+            $ext->setData($post);
+            $packageVersion = $this->getRequest()->getPost('version_ids');
+            if (is_array($packageVersion)) {
+                if (in_array(\Magento\Framework\Connect\Package::PACKAGE_VERSION_2X, $packageVersion)) {
+                    $ext->createPackage();
+                }
+                if (in_array(\Magento\Framework\Connect\Package::PACKAGE_VERSION_1X, $packageVersion)) {
+                    $ext->createPackageV1x();
+                }
+            }
+            $this->_redirect('adminhtml/*');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('adminhtml/*');
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Something went wrong creating the package.'));
+            $this->_redirect('adminhtml/*');
+        }
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Edit.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..88ad8d1290fcda9601fb5c2872eb14db2eb2cbe6
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Edit.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Edit extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Edit Extension Package Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Extension'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Connect::system_extensions_custom');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Grid.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5f71cee5308b23eed8471a43f9e1ba0ba02557a
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Grid extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Grid for loading packages
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Index.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..435e540486a15b00fbd05d06d59c6b0de0bf8429
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Index.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Index extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Redirect to edit Extension Package action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Package Extensions'));
+
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Load.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Load.php
new file mode 100644
index 0000000000000000000000000000000000000000..0626253f323907610be22a8cd09233c8c3818c91
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Load.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Load extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Load Local Extension Package
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $packageName = base64_decode(strtr($this->getRequest()->getParam('id'), '-_,', '+/='));
+        if ($packageName) {
+            $session = $this->_objectManager->get('Magento\Connect\Model\Session');
+            try {
+                $data = $this->_objectManager->get('Magento\Connect\Helper\Data')->loadLocalPackage($packageName);
+                if (!$data) {
+                    throw new \Magento\Framework\Model\Exception(__('Something went wrong loading the package data.'));
+                }
+                $data = array_merge($data, array('file_name' => $packageName));
+                $session->setCustomExtensionPackageFormData($data);
+                $this->messageManager->addSuccess(__('The package %1 data has been loaded.', $packageName));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+        $this->_redirect('adminhtml/*/edit');
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Loadtab.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Loadtab.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6fcb3b1dc18f3da3e430a555b26bc057bd8a441
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Loadtab.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Loadtab extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Load Grid with Local Packages
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Reset.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Reset.php
new file mode 100644
index 0000000000000000000000000000000000000000..538d7b5d73c28fd6ea48a141810b8e1b0931f3d6
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Reset.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Reset extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Reset Extension Package form data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_objectManager->get('Magento\Connect\Model\Session')->unsCustomExtensionPackageFormData();
+        $this->_redirect('adminhtml/*/edit');
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Save.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..b10b82c40a8c4b59f96dac0f1a65096b01db99a3
--- /dev/null
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Custom/Save.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Custom;
+
+class Save extends \Magento\Connect\Controller\Adminhtml\Extension\Custom
+{
+    /**
+     * Save Extension Package
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Connect\Model\Session');
+        $p = $this->getRequest()->getPost();
+
+        if (!empty($p['_create'])) {
+            $create = true;
+            unset($p['_create']);
+        }
+
+        if ($p['file_name'] == '') {
+            $p['file_name'] = $p['name'];
+        }
+
+        $session->setCustomExtensionPackageFormData($p);
+        try {
+            $ext = $this->_objectManager->create('Magento\Connect\Model\Extension');
+            /** @var $ext \Magento\Connect\Model\Extension */
+            $ext->setData($p);
+            if ($ext->savePackage()) {
+                $this->messageManager->addSuccess(__('The package data has been saved.'));
+            } else {
+                $this->messageManager->addError(__('Something went wrong saving the package data.'));
+                $this->_redirect('adminhtml/*/edit');
+            }
+            if (empty($create)) {
+                $this->_redirect('adminhtml/*/edit');
+            } else {
+                $this->_forward('create');
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('adminhtml/*');
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Something went wrong saving the package.'));
+            $this->_redirect('adminhtml/*');
+        }
+    }
+}
diff --git a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Local.php b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Local/Index.php
similarity index 84%
rename from app/code/Magento/Connect/Controller/Adminhtml/Extension/Local.php
rename to app/code/Magento/Connect/Controller/Adminhtml/Extension/Local/Index.php
index 4114f006ec9abeca226807d064c5edd5e6526446..548041728b7ff0e25a58ebbad0c62658b4445191 100644
--- a/app/code/Magento/Connect/Controller/Adminhtml/Extension/Local.php
+++ b/app/code/Magento/Connect/Controller/Adminhtml/Extension/Local/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,22 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Connect\Controller\Adminhtml\Extension\Local;
 
-/**
- * Local Magento Connect Controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Connect\Controller\Adminhtml\Extension;
-
-class Local extends \Magento\Backend\App\Action
+class Index extends \Magento\Backend\App\Action
 {
     /**
      * Redirect to Magento Connect
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $url = $this->_objectManager->get(
             'Magento\Store\Model\StoreManagerInterface'
diff --git a/app/code/Magento/Contact/Controller/Index.php b/app/code/Magento/Contact/Controller/Index.php
index 66f4f023fe5f0c651fb676d040111b012b298452..e52e7cb3c484050489c5b5dcdd49d78bad128fe0 100644
--- a/app/code/Magento/Contact/Controller/Index.php
+++ b/app/code/Magento/Contact/Controller/Index.php
@@ -106,88 +106,4 @@ class Index extends \Magento\Framework\App\Action\Action
         }
         return parent::dispatch($request);
     }
-
-    /**
-     * Show Contact Us page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()
-            ->getBlock('contactForm')
-            ->setFormAction($this->_url->getUrl('*/*/post', ['_secure' => true]));
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Post user question
-     *
-     * @return void
-     * @throws \Exception
-     */
-    public function postAction()
-    {
-        $post = $this->getRequest()->getPost();
-        if (!$post) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        $this->inlineTranslation->suspend();
-        try {
-            $postObject = new \Magento\Framework\Object();
-            $postObject->setData($post);
-
-            $error = false;
-
-            if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) {
-                $error = true;
-            }
-            if (!\Zend_Validate::is(trim($post['comment']), 'NotEmpty')) {
-                $error = true;
-            }
-            if (!\Zend_Validate::is(trim($post['email']), 'EmailAddress')) {
-                $error = true;
-            }
-            if (\Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) {
-                $error = true;
-            }
-            if ($error) {
-                throw new \Exception();
-            }
-
-            $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
-            $transport = $this->_transportBuilder
-                ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope))
-                ->setTemplateOptions(
-                    [
-                        'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
-                        'store' => $this->storeManager->getStore()->getId()
-                    ]
-                )
-                ->setTemplateVars(array('data' => $postObject))
-                ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope))
-                ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope))
-                ->setReplyTo($post['email'])
-                ->getTransport();
-
-            $transport->sendMessage();
-            $this->inlineTranslation->resume();
-            $this->messageManager->addSuccess(
-                __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.')
-            );
-            $this->_redirect('*/*/');
-            return;
-        } catch (\Exception $e) {
-            $this->inlineTranslation->resume();
-            $this->messageManager->addError(
-                __('We can\'t process your request right now. Sorry, that\'s all we know.')
-            );
-            $this->_redirect('*/*/');
-            return;
-        }
-    }
 }
diff --git a/app/code/Magento/Contact/Controller/Index/Index.php b/app/code/Magento/Contact/Controller/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6ad2210d0f9280c20f1f4ee1a22135104de6c9e
--- /dev/null
+++ b/app/code/Magento/Contact/Controller/Index/Index.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Contact\Controller\Index;
+
+class Index extends \Magento\Contact\Controller\Index
+{
+    /**
+     * Show Contact Us page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()
+            ->getBlock('contactForm')
+            ->setFormAction($this->_url->getUrl('*/*/post', ['_secure' => true]));
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Contact/Controller/Index/Post.php b/app/code/Magento/Contact/Controller/Index/Post.php
new file mode 100644
index 0000000000000000000000000000000000000000..e61a90ee6e60f49243f8a18c4fd9e843f12d3671
--- /dev/null
+++ b/app/code/Magento/Contact/Controller/Index/Post.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Contact\Controller\Index;
+
+class Post extends \Magento\Contact\Controller\Index
+{
+    /**
+     * Post user question
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function execute()
+    {
+        $post = $this->getRequest()->getPost();
+        if (!$post) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        $this->inlineTranslation->suspend();
+        try {
+            $postObject = new \Magento\Framework\Object();
+            $postObject->setData($post);
+
+            $error = false;
+
+            if (!\Zend_Validate::is(trim($post['name']), 'NotEmpty')) {
+                $error = true;
+            }
+            if (!\Zend_Validate::is(trim($post['comment']), 'NotEmpty')) {
+                $error = true;
+            }
+            if (!\Zend_Validate::is(trim($post['email']), 'EmailAddress')) {
+                $error = true;
+            }
+            if (\Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) {
+                $error = true;
+            }
+            if ($error) {
+                throw new \Exception();
+            }
+
+            $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
+            $transport = $this->_transportBuilder
+                ->setTemplateIdentifier($this->scopeConfig->getValue(self::XML_PATH_EMAIL_TEMPLATE, $storeScope))
+                ->setTemplateOptions(
+                    [
+                        'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
+                        'store' => $this->storeManager->getStore()->getId()
+                    ]
+                )
+                ->setTemplateVars(array('data' => $postObject))
+                ->setFrom($this->scopeConfig->getValue(self::XML_PATH_EMAIL_SENDER, $storeScope))
+                ->addTo($this->scopeConfig->getValue(self::XML_PATH_EMAIL_RECIPIENT, $storeScope))
+                ->setReplyTo($post['email'])
+                ->getTransport();
+
+            $transport->sendMessage();
+            $this->inlineTranslation->resume();
+            $this->messageManager->addSuccess(
+                __('Thanks for contacting us with your comments and questions. We\'ll respond to you very soon.')
+            );
+            $this->_redirect('*/*/');
+            return;
+        } catch (\Exception $e) {
+            $this->inlineTranslation->resume();
+            $this->messageManager->addError(
+                __('We can\'t process your request right now. Sorry, that\'s all we know.')
+            );
+            $this->_redirect('*/*/');
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Core/App/Router/Base.php b/app/code/Magento/Core/App/Router/Base.php
index 54742020914e67524586a2734721636e5a836a08..42c8b2603ca9082d43857a649825abd4e0d60e31 100644
--- a/app/code/Magento/Core/App/Router/Base.php
+++ b/app/code/Magento/Core/App/Router/Base.php
@@ -25,8 +25,20 @@
  */
 namespace Magento\Core\App\Router;
 
-class Base extends \Magento\Framework\App\Router\AbstractRouter
+use Magento\Framework\App\RequestInterface;
+
+class Base implements \Magento\Framework\App\RouterInterface
 {
+    /**
+     * @var \Magento\Framework\App\ActionFactory
+     */
+    protected $actionFactory;
+
+    /**
+     * @var string
+     */
+    protected $actionInterface = '\Magento\Framework\App\ActionInterface';
+
     /**
      * @var array
      */
@@ -42,7 +54,7 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * Order sensitive
      * @var string[]
      */
-    protected $_requiredParams = array('moduleFrontName', 'controllerName', 'actionName');
+    protected $_requiredParams = array('moduleFrontName', 'actionPath', 'actionName');
 
     /**
      * @var \Magento\Framework\App\Route\ConfigInterface
@@ -94,6 +106,29 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
     protected $nameBuilder;
 
     /**
+     * @var array
+     */
+    protected $reservedNames = ['new', 'print', 'switch', 'return'];
+
+    /**
+     * Allows to control if we need to enable no route functionality in current router
+     *
+     * @var bool
+     */
+    protected $applyNoRoute = false;
+
+    /**
+     * @var string
+     */
+    protected $pathPrefix = null;
+
+    /**
+     * @var \Magento\Framework\App\Router\ActionList
+     */
+    protected $actionList;
+
+    /**
+     * @param \Magento\Framework\App\Router\ActionList $actionList
      * @param \Magento\Framework\App\ActionFactory $actionFactory
      * @param \Magento\Framework\App\DefaultPathInterface $defaultPath
      * @param \Magento\Framework\App\ResponseFactory $responseFactory
@@ -108,6 +143,7 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @throws \InvalidArgumentException
      */
     public function __construct(
+        \Magento\Framework\App\Router\ActionList $actionList,
         \Magento\Framework\App\ActionFactory $actionFactory,
         \Magento\Framework\App\DefaultPathInterface $defaultPath,
         \Magento\Framework\App\ResponseFactory $responseFactory,
@@ -120,7 +156,8 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
         $routerId,
         \Magento\Framework\Code\NameBuilder $nameBuilder
     ) {
-        parent::__construct($actionFactory);
+        $this->actionList = $actionList;
+        $this->actionFactory = $actionFactory;
         $this->_responseFactory = $responseFactory;
         $this->_defaultPath = $defaultPath;
         $this->_routeConfig = $routeConfig;
@@ -140,9 +177,9 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      */
     public function match(\Magento\Framework\App\RequestInterface $request)
     {
-        $params = $this->_parseRequest($request);
+        $params = $this->parseRequest($request);
 
-        return $this->_matchController($request, $params);
+        return $this->matchAction($request, $params);
     }
 
     /**
@@ -151,7 +188,7 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @param \Magento\Framework\App\RequestInterface $request
      * @return array
      */
-    protected function _parseRequest(\Magento\Framework\App\RequestInterface $request)
+    protected function parseRequest(\Magento\Framework\App\RequestInterface $request)
     {
         $output = array();
 
@@ -175,7 +212,7 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @param string $param
      * @return string|null
      */
-    protected function _matchModuleFrontName(\Magento\Framework\App\RequestInterface $request, $param)
+    protected function matchModuleFrontName(\Magento\Framework\App\RequestInterface $request, $param)
     {
         // get module name
         if ($request->getModuleName()) {
@@ -199,37 +236,20 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @param string $param
      * @return string
      */
-    protected function _matchControllerName(\Magento\Framework\App\RequestInterface $request, $param)
+    protected function matchActionPath(\Magento\Framework\App\RequestInterface $request, $param)
     {
         if ($request->getControllerName()) {
-            $controller = $request->getControllerName();
+            $actionPath = $request->getControllerName();
         } elseif (!empty($param)) {
-            $controller = $param;
+            $actionPath = $param;
         } else {
-            $controller = $this->_defaultPath->getPart('controller');
-            $request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, ltrim($request->getOriginalPathInfo(), '/'));
-        }
-        return $controller;
-    }
-
-    /**
-     * Match controller name
-     *
-     * @param \Magento\Framework\App\RequestInterface $request
-     * @param string $param
-     * @return string
-     */
-    protected function _matchActionName(\Magento\Framework\App\RequestInterface $request, $param)
-    {
-        if ($request->getActionName()) {
-            $action = $request->getActionName();
-        } elseif (empty($param)) {
-            $action = $this->_defaultPath->getPart('action');
-        } else {
-            $action = $param;
+            $actionPath = $this->_defaultPath->getPart('controller');
+            $request->setAlias(
+                \Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS,
+                ltrim($request->getOriginalPathInfo(), '/')
+            );
         }
-
-        return $action;
+        return $actionPath;
     }
 
     /**
@@ -239,22 +259,19 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @param \Magento\Framework\App\RequestInterface $request
      * @return \Magento\Framework\App\Action\Action|null
      */
-    protected function _getNotFoundControllerInstance($currentModuleName, \Magento\Framework\App\RequestInterface $request)
+    protected function getNotFoundAction($currentModuleName, RequestInterface $request)
     {
-        if (!$this->_noRouteShouldBeApplied()) {
+        if (!$this->applyNoRoute) {
             return null;
         }
 
-        $controllerClassName = $this->getControllerClassName($currentModuleName, 'index');
-        if (!$controllerClassName
-            || !method_exists($controllerClassName, 'norouteAction')
-            || !is_callable([$controllerClassName, 'norouteAction'])
-        ) {
+        $actionClassName = $this->getActionClassName($currentModuleName, 'noroute');
+        if (!$actionClassName || !is_subclass_of($actionClassName, $this->actionInterface)) {
             return null;
         }
 
-        // instantiate controller class
-        return $this->_actionFactory->createController($controllerClassName, array('request' => $request));
+        // instantiate action class
+        return $this->actionFactory->create($actionClassName, array('request' => $request));
     }
 
     /**
@@ -264,9 +281,9 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      * @param array $params
      * @return \Magento\Framework\App\Action\Action|null
      */
-    protected function _matchController(\Magento\Framework\App\RequestInterface $request, array $params)
+    protected function matchAction(\Magento\Framework\App\RequestInterface $request, array $params)
     {
-        $moduleFrontName = $this->_matchModuleFrontName($request, $params['moduleFrontName']);
+        $moduleFrontName = $this->matchModuleFrontName($request, $params['moduleFrontName']);
         if (empty($moduleFrontName)) {
             return null;
         }
@@ -284,36 +301,30 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
          * Going through modules to find appropriate controller
          */
         $currentModuleName = null;
-        $controller = null;
+        $actionPath = null;
         $action = null;
-        $controllerInstance = null;
+        $actionInstance = null;
 
         $request->setRouteName($this->_routeConfig->getRouteByFrontName($moduleFrontName));
-        $controller = $this->_matchControllerName($request, $params['controllerName']);
-        $action = $this->_matchActionName($request, $params['actionName']);
-        $this->_checkShouldBeSecure($request, '/' . $moduleFrontName . '/' . $controller . '/' . $action);
+        $actionPath = $this->matchActionPath($request, $params['actionPath']);
+        $action = $request->getActionName() ?: ($params['actionName'] ?: $this->_defaultPath->getPart('action'));
+        $this->_checkShouldBeSecure($request, '/' . $moduleFrontName . '/' . $actionPath . '/' . $action);
 
         foreach ($modules as $moduleName) {
             $currentModuleName = $moduleName;
 
-            $controllerClassName = $this->getControllerClassName($moduleName, $controller);
-            if (!$controllerClassName
-                || !method_exists($controllerClassName, $action . 'Action')
-                || !is_callable([$controllerClassName, $action . 'Action'])
-            ) {
+            $actionClassName = $this->actionList->get($moduleName, $this->pathPrefix, $actionPath, $action);
+            if (!$actionClassName || !is_subclass_of($actionClassName, $this->actionInterface)) {
                 continue;
             }
 
-            $controllerInstance = $this->_actionFactory->createController(
-                $controllerClassName,
-                array('request' => $request)
-            );
+            $actionInstance = $this->actionFactory->create($actionClassName, array('request' => $request));
             break;
         }
 
-        if (null == $controllerInstance) {
-            $controllerInstance = $this->_getNotFoundControllerInstance($currentModuleName, $request);
-            if (is_null($controllerInstance)) {
+        if (null == $actionInstance) {
+            $actionInstance = $this->getNotFoundAction($currentModuleName, $request);
+            if (is_null($actionInstance)) {
                 return null;
             }
             $action = 'noroute';
@@ -321,13 +332,13 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
 
         // set values only after all the checks are done
         $request->setModuleName($moduleFrontName);
-        $request->setControllerName($controller);
+        $request->setControllerName($actionPath);
         $request->setActionName($action);
         $request->setControllerModule($currentModuleName);
         if (isset($params['variables'])) {
             $request->setParams($params['variables']);
         }
-        return $controllerInstance;
+        return $actionInstance;
     }
 
     /**
@@ -340,26 +351,17 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
         return $this->_scopeConfig->getValue('web/default/front', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
     }
 
-    /**
-     * Allow to control if we need to enable no route functionality in current router
-     *
-     * @return bool
-     */
-    protected function _noRouteShouldBeApplied()
-    {
-        return false;
-    }
-
     /**
      * Build controller class name
      *
      * @param string $module
-     * @param string $controller
+     * @param string $actionPath
      * @return string
      */
-    public function getControllerClassName($module, $controller)
+    public function getActionClassName($module, $actionPath)
     {
-        return $this->nameBuilder->buildClassName(array($module, 'Controller', $controller));
+        $prefix = $this->pathPrefix ? 'Controller\\' . $this->pathPrefix  : 'Controller';
+        return $this->nameBuilder->buildClassName(array($module, $prefix, $actionPath));
     }
 
     /**
@@ -405,12 +407,8 @@ class Base extends \Magento\Framework\App\Router\AbstractRouter
      */
     protected function _getCurrentSecureUrl($request)
     {
-        $alias = $request->getAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS);
-        if ($alias) {
-            return $this->_storeManager->getStore()->getBaseUrl('link', true) . ltrim($alias, '/');
-        }
-
-        return $this->_storeManager->getStore()->getBaseUrl('link', true) . ltrim($request->getPathInfo(), '/');
+        $alias = $request->getAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS) || $request->getPathInfo();
+        return $this->_storeManager->getStore()->getBaseUrl('link', true) . ltrim($alias, '/');
     }
 
     /**
diff --git a/app/code/Magento/Core/App/Router/NoRouteHandler.php b/app/code/Magento/Core/App/Router/NoRouteHandler.php
index 9b2d942388cbd4e3eaeae53850f69a05ae1282d8..8e8d8eb84ae278a400c722168b70c65b061bcc38 100644
--- a/app/code/Magento/Core/App/Router/NoRouteHandler.php
+++ b/app/code/Magento/Core/App/Router/NoRouteHandler.php
@@ -58,10 +58,10 @@ class NoRouteHandler implements \Magento\Framework\App\Router\NoRouteHandlerInte
         }
 
         $moduleName = isset($noRoute[0]) ? $noRoute[0] : 'core';
-        $controllerName = isset($noRoute[1]) ? $noRoute[1] : 'index';
+        $actionPath = isset($noRoute[1]) ? $noRoute[1] : 'index';
         $actionName = isset($noRoute[2]) ? $noRoute[2] : 'index';
 
-        $request->setModuleName($moduleName)->setControllerName($controllerName)->setActionName($actionName);
+        $request->setModuleName($moduleName)->setControllerName($actionPath)->setActionName($actionName);
 
         return true;
     }
diff --git a/dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Index.php b/app/code/Magento/Core/Controller/Index/Index.php
similarity index 85%
rename from dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Index.php
rename to app/code/Magento/Core/Controller/Index/Index.php
index 1ae9761009a51bc5d10855f91581eb74b7089a5a..001fde72b85e0374df30b9820935574ebd4a35a2 100644
--- a/dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Core/Controller/Index/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,17 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\TestFixture\Controller\Adminhtml;
+namespace Magento\Core\Controller\Index;
 
-/**
- * Mock index controller class
- */
-class Index
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
-     * No route action
+     * @return void
      */
-    public function norouteAction()
+    public function execute()
     {
     }
 }
diff --git a/app/code/Magento/Core/Controller/Index.php b/app/code/Magento/Core/Controller/Index/NoCookies.php
similarity index 75%
rename from app/code/Magento/Core/Controller/Index.php
rename to app/code/Magento/Core/Controller/Index/NoCookies.php
index 70e0fc57e5944e3d632779ced6f2bbfb2df7070d..7b9d0bdc93a5925c4e409ee48fefbbb268e7c85a 100644
--- a/app/code/Magento/Core/Controller/Index.php
+++ b/app/code/Magento/Core/Controller/Index/NoCookies.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,35 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Core\Controller;
+namespace Magento\Core\Controller\Index;
 
-class Index extends \Magento\Framework\App\Action\Action
+class NoCookies extends \Magento\Framework\App\Action\Action
 {
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-    }
-
-    /**
-     * 404 not found action
-     *
-     * @return void
-     */
-    public function notFoundAction()
-    {
-        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
-        $this->getResponse()->setHttpResponseCode(404);
-        $this->getResponse()->setBody(__('Requested resource not found'));
-    }
-
     /**
      * No cookies action
      *
      * @return void
      */
-    public function noCookiesAction()
+    public function execute()
     {
         $redirect = new \Magento\Framework\Object();
         $this->_eventManager->dispatch(
diff --git a/app/code/Magento/Core/Controller/Index/NotFound.php b/app/code/Magento/Core/Controller/Index/NotFound.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e220662afb270ea7ad03d5c961e6385ca5614ae
--- /dev/null
+++ b/app/code/Magento/Core/Controller/Index/NotFound.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Core\Controller\Index;
+
+class NotFound extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * 404 not found action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('HTTP/1.1', '404 Not Found');
+        $this->getResponse()->setHttpResponseCode(404);
+        $this->getResponse()->setBody(__('Requested resource not found'));
+    }
+}
diff --git a/app/code/Magento/Core/Controller/Noroute.php b/app/code/Magento/Core/Controller/Noroute/Index.php
similarity index 91%
rename from app/code/Magento/Core/Controller/Noroute.php
rename to app/code/Magento/Core/Controller/Noroute/Index.php
index 10be729791cd4a028148c62bf08133d0d88420a5..a9dfd50978dcb4511d32ba75dbc980da40d910b6 100644
--- a/app/code/Magento/Core/Controller/Noroute.php
+++ b/app/code/Magento/Core/Controller/Noroute/Index.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Noroute application handler.
  *
  * Magento
  *
@@ -23,18 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Core\Controller;
+namespace Magento\Core\Controller\Noroute;
 
-use Magento\Framework\App\Action\Action;
-
-class Noroute extends Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * Noroute application handler
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $status = $this->getRequest()->getParam('__status__');
         if (!$status instanceof \Magento\Framework\Object) {
diff --git a/app/code/Magento/Cron/Model/Observer.php b/app/code/Magento/Cron/Model/Observer.php
index d48ba937359839af3c8fe444cb6873112c136df8..85e2a284bf31566f20568616cbe71dbd67f2815a 100644
--- a/app/code/Magento/Cron/Model/Observer.php
+++ b/app/code/Magento/Cron/Model/Observer.php
@@ -257,7 +257,7 @@ class Observer
         /**
          * check if schedule generation is needed
          */
-        $lastRun = (int)$this->_cache->load(self::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT);
+        $lastRun = (int)$this->_cache->load(self::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT . $groupId);
         $rawSchedulePeriod = (int)$this->_scopeConfig->getValue(
             'system/cron/' . $groupId . '/' . self::XML_PATH_SCHEDULE_GENERATE_EVERY,
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
@@ -283,7 +283,7 @@ class Observer
         /**
          * save time schedules generation was ran with no expiration
          */
-        $this->_cache->save(time(), self::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT, array('crontab'), null);
+        $this->_cache->save(time(), self::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT . $groupId, array('crontab'), null);
 
         return $this;
     }
@@ -329,7 +329,7 @@ class Observer
     protected function _cleanup($groupId)
     {
         // check if history cleanup is needed
-        $lastCleanup = (int)$this->_cache->load(self::CACHE_KEY_LAST_HISTORY_CLEANUP_AT);
+        $lastCleanup = (int)$this->_cache->load(self::CACHE_KEY_LAST_HISTORY_CLEANUP_AT . $groupId);
         $historyCleanUp = (int)$this->_scopeConfig->getValue(
             'system/cron/' . $groupId . '/' . self::XML_PATH_HISTORY_CLEANUP_EVERY,
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE
@@ -369,7 +369,7 @@ class Observer
         }
 
         // save time history cleanup was ran with no expiration
-        $this->_cache->save(time(), self::CACHE_KEY_LAST_HISTORY_CLEANUP_AT, array('crontab'), null);
+        $this->_cache->save(time(), self::CACHE_KEY_LAST_HISTORY_CLEANUP_AT . $groupId, array('crontab'), null);
 
         return $this;
     }
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency.php
index efa544b4d64a758607c72616529227973260992b..6e15bfc17609ab9c868b3528e48d3f081f445eb5 100644
--- a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency.php
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency.php
@@ -48,115 +48,6 @@ class Currency extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Init currency by currency code from request
-     *
-     * @return $this
-     */
-    protected function _initCurrency()
-    {
-        $code = $this->getRequest()->getParam('currency');
-        $currency = $this->_objectManager->create('Magento\Directory\Model\Currency')->load($code);
-
-        $this->_coreRegistry->register('currency', $currency);
-        return $this;
-    }
-
-    /**
-     * Currency management main page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Currency Rates'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_CurrencySymbol::system_currency_rates');
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\CurrencySymbol\Block\Adminhtml\System\Currency')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Fetch rates action
-     *
-     * @return void
-     * @throws \Exception|\Magento\Framework\Model\Exception
-     */
-    public function fetchRatesAction()
-    {
-        /** @var \Magento\Backend\Model\Session $backendSession */
-        $backendSession = $this->_objectManager->get('Magento\Backend\Model\Session');
-        try {
-            $service = $this->getRequest()->getParam('rate_services');
-            $this->_getSession()->setCurrencyRateService($service);
-            if (!$service) {
-                throw new \Exception(__('Please specify a correct Import Service.'));
-            }
-            try {
-                /** @var \Magento\Directory\Model\Currency\Import\ImportInterface $importModel */
-                $importModel = $this->_objectManager->get(
-                    'Magento\Directory\Model\Currency\Import\Factory'
-                )->create(
-                    $service
-                );
-            } catch (\Exception $e) {
-                throw new \Magento\Framework\Model\Exception(__('We can\'t initialize the import model.'));
-            }
-            $rates = $importModel->fetchRates();
-            $errors = $importModel->getMessages();
-            if (sizeof($errors) > 0) {
-                foreach ($errors as $error) {
-                    $this->messageManager->addWarning($error);
-                }
-                $this->messageManager->addWarning(
-                    __('All possible rates were fetched, please click on "Save" to apply')
-                );
-            } else {
-                $this->messageManager->addSuccess(__('All rates were fetched, please click on "Save" to apply'));
-            }
-
-            $backendSession->setRates($rates);
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Save rates action
-     *
-     * @return void
-     */
-    public function saveRatesAction()
-    {
-        $data = $this->getRequest()->getParam('rate');
-        if (is_array($data)) {
-            try {
-                foreach ($data as $currencyCode => $rate) {
-                    foreach ($rate as $currencyTo => $value) {
-                        $value = abs($this->_objectManager->get('Magento\Framework\Locale\FormatInterface')->getNumber($value));
-                        $data[$currencyCode][$currencyTo] = $value;
-                        if ($value == 0) {
-                            $this->messageManager->addWarning(
-                                __('Please correct the input data for %1 => %2 rate', $currencyCode, $currencyTo)
-                            );
-                        }
-                    }
-                }
-
-                $this->_objectManager->create('Magento\Directory\Model\Currency')->saveRates($data);
-                $this->messageManager->addSuccess(__('All valid rates have been saved.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-
-        $this->_redirect('adminhtml/*/');
-    }
-
     /**
      * Check if allowed
      *
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d98ce7d381e55092fc09c39ec1c5aa91558717b
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency;
+
+class FetchRates extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency
+{
+    /**
+     * Fetch rates action
+     *
+     * @return void
+     * @throws \Exception|\Magento\Framework\Model\Exception
+     */
+    public function execute()
+    {
+        /** @var \Magento\Backend\Model\Session $backendSession */
+        $backendSession = $this->_objectManager->get('Magento\Backend\Model\Session');
+        try {
+            $service = $this->getRequest()->getParam('rate_services');
+            $this->_getSession()->setCurrencyRateService($service);
+            if (!$service) {
+                throw new \Exception(__('Please specify a correct Import Service.'));
+            }
+            try {
+                /** @var \Magento\Directory\Model\Currency\Import\ImportInterface $importModel */
+                $importModel = $this->_objectManager->get(
+                    'Magento\Directory\Model\Currency\Import\Factory'
+                )->create(
+                    $service
+                );
+            } catch (\Exception $e) {
+                throw new \Magento\Framework\Model\Exception(__('We can\'t initialize the import model.'));
+            }
+            $rates = $importModel->fetchRates();
+            $errors = $importModel->getMessages();
+            if (sizeof($errors) > 0) {
+                foreach ($errors as $error) {
+                    $this->messageManager->addWarning($error);
+                }
+                $this->messageManager->addWarning(
+                    __('All possible rates were fetched, please click on "Save" to apply')
+                );
+            } else {
+                $this->messageManager->addSuccess(__('All rates were fetched, please click on "Save" to apply'));
+            }
+
+            $backendSession->setRates($rates);
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/Index.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b7b0c1e0dc5086ebcb7663c66643be53654d1ea
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/Index.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency;
+
+class Index extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency
+{
+    /**
+     * Currency management main page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Currency Rates'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_CurrencySymbol::system_currency_rates');
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\CurrencySymbol\Block\Adminhtml\System\Currency')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php
new file mode 100644
index 0000000000000000000000000000000000000000..6051dfa9b445ba8a8f7714756acd10168acc86f5
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/SaveRates.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency;
+
+class SaveRates extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currency
+{
+    /**
+     * Save rates action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getParam('rate');
+        if (is_array($data)) {
+            try {
+                foreach ($data as $currencyCode => $rate) {
+                    foreach ($rate as $currencyTo => $value) {
+                        $value = abs($this->_objectManager->get('Magento\Framework\Locale\FormatInterface')->getNumber($value));
+                        $data[$currencyCode][$currencyTo] = $value;
+                        if ($value == 0) {
+                            $this->messageManager->addWarning(
+                                __('Please correct the input data for %1 => %2 rate', $currencyCode, $currencyTo)
+                            );
+                        }
+                    }
+                }
+
+                $this->_objectManager->create('Magento\Directory\Model\Currency')->saveRates($data);
+                $this->messageManager->addSuccess(__('All valid rates have been saved.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol.php
index fa690fcd4c5ad2e9cc1ada7238832861d418b86e..b460169114f3a7328e5130e786375e8c2c14b18a 100644
--- a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol.php
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol.php
@@ -31,69 +31,6 @@ namespace Magento\CurrencySymbol\Controller\Adminhtml\System;
 
 class Currencysymbol extends \Magento\Backend\App\Action
 {
-    /**
-     * Show Currency Symbols Management dialog
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        // set active menu and breadcrumbs
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_CurrencySymbol::system_currency_symbols'
-        )->_addBreadcrumb(
-            __('System'),
-            __('System')
-        )->_addBreadcrumb(
-            __('Manage Currency Rates'),
-            __('Manage Currency Rates')
-        );
-
-        $this->_title->add(__('Currency Symbols'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save custom Currency symbol
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $symbolsDataArray = $this->getRequest()->getParam('custom_currency_symbol', null);
-        if (is_array($symbolsDataArray)) {
-            foreach ($symbolsDataArray as &$symbolsData) {
-                /** @var $filterManager \Magento\Framework\Filter\FilterManager */
-                $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
-                $symbolsData = $filterManager->stripTags($symbolsData);
-            }
-        }
-
-        try {
-            $this->_objectManager->create(
-                'Magento\CurrencySymbol\Model\System\Currencysymbol'
-            )->setCurrencySymbolsData(
-                $symbolsDataArray
-            );
-            $this->messageManager->addSuccess(__('The custom currency symbols were applied.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        }
-
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
-    /**
-     * Resets custom Currency symbol for all store views, websites and default value
-     *
-     * @return void
-     */
-    public function resetAction()
-    {
-        $this->_objectManager->create('Magento\CurrencySymbol\Model\System\Currencysymbol')->resetValues();
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
 
     /**
      * Check the permission to run it
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Index.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..9195c89fdf37e991af1ed222f100848163225a12
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Index.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol;
+
+class Index extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol
+{
+    /**
+     * Show Currency Symbols Management dialog
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // set active menu and breadcrumbs
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_CurrencySymbol::system_currency_symbols'
+        )->_addBreadcrumb(
+            __('System'),
+            __('System')
+        )->_addBreadcrumb(
+            __('Manage Currency Rates'),
+            __('Manage Currency Rates')
+        );
+
+        $this->_title->add(__('Currency Symbols'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Reset.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Reset.php
new file mode 100644
index 0000000000000000000000000000000000000000..685d960a52026ce6b9c2402ff35cbef1e3e8ef35
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Reset.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol;
+
+class Reset extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol
+{
+    /**
+     * Resets custom Currency symbol for all store views, websites and default value
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_objectManager->create('Magento\CurrencySymbol\Model\System\Currencysymbol')->resetValues();
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..f45e072c410ddb92f778a14ea5dc1f89c0e7ea00
--- /dev/null
+++ b/app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currencysymbol/Save.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol;
+
+class Save extends \Magento\CurrencySymbol\Controller\Adminhtml\System\Currencysymbol
+{
+    /**
+     * Save custom Currency symbol
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $symbolsDataArray = $this->getRequest()->getParam('custom_currency_symbol', null);
+        if (is_array($symbolsDataArray)) {
+            foreach ($symbolsDataArray as &$symbolsData) {
+                /** @var $filterManager \Magento\Framework\Filter\FilterManager */
+                $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
+                $symbolsData = $filterManager->stripTags($symbolsData);
+            }
+        }
+
+        try {
+            $this->_objectManager->create(
+                'Magento\CurrencySymbol\Model\System\Currencysymbol'
+            )->setCurrencySymbolsData(
+                $symbolsDataArray
+            );
+            $this->messageManager->addSuccess(__('The custom currency symbols were applied.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        }
+
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Edit.php b/app/code/Magento/Customer/Block/Adminhtml/Edit.php
index 4ec8f72f5bb6f0bddcff6d3a9da38a3637eecf43..0f67142df521851e028a2d42913b0b8b1d4b0ef8 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Edit.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Edit.php
@@ -51,14 +51,14 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     /**
      * Constructor
      *
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param CustomerAccountServiceInterface $customerAccountService
      * @param \Magento\Customer\Helper\View $viewHelper
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         CustomerAccountServiceInterface $customerAccountService,
         \Magento\Customer\Helper\View $viewHelper,
@@ -82,7 +82,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $customerId = $this->getCustomerId();
 
         if ($customerId && $this->_authorization->isAllowed('Magento_Sales::create')) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'order',
                 array(
                     'label' => __('Create Order'),
@@ -95,21 +95,21 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Customer'));
-        $this->_updateButton('delete', 'label', __('Delete Customer'));
+        $this->buttonList->update('save', 'label', __('Save Customer'));
+        $this->buttonList->update('delete', 'label', __('Delete Customer'));
 
         if ($customerId && !$this->_customerAccountService->canModify($customerId)) {
-            $this->_removeButton('save');
-            $this->_removeButton('reset');
+            $this->buttonList->remove('save');
+            $this->buttonList->remove('reset');
         }
 
         if (!$customerId || !$this->_customerAccountService->canDelete($customerId)) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
 
         if ($customerId) {
             $url = $this->getUrl('customer/index/resetPassword', array('customer_id' => $customerId));
-            $this->_addButton(
+            $this->buttonList->add(
                 'reset_password',
                 array(
                     'label' => __('Reset Password'),
@@ -191,7 +191,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     {
         $customerId = $this->getCustomerId();
         if (!$customerId || $this->_customerAccountService->canModify($customerId)) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'save_and_continue',
                 array(
                     'label' => __('Save and Continue Edit'),
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit.php b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit.php
index 0aff03491c58e3cacfce97ddd065d54cc5757c9f..3746888bf8bdc69378974e20aaa1724a91872581 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit.php
@@ -47,13 +47,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     /**
      * Constructor
      *
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupService
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Customer\Service\V1\CustomerGroupServiceInterface $groupService,
         array $data = array()
@@ -76,12 +76,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml_group';
         $this->_blockGroup = 'Magento_Customer';
 
-        $this->_updateButton('save', 'label', __('Save Customer Group'));
-        $this->_updateButton('delete', 'label', __('Delete Customer Group'));
+        $this->buttonList->update('save', 'label', __('Save Customer Group'));
+        $this->buttonList->update('delete', 'label', __('Delete Customer Group'));
 
         $groupId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_GROUP_ID);
         if (!$groupId || !$this->_groupService->canDelete($groupId)) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
     }
 
diff --git a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
index fb3f93a51fdf49af84414da426d2e294cdd0192d..d269e6189849954a8de88ae45f135767d53d5dd4 100644
--- a/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
+++ b/app/code/Magento/Customer/Block/Adminhtml/Group/Edit/Form.php
@@ -124,7 +124,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'title' => __('Tax Class'),
                 'class' => 'required-entry',
                 'required' => true,
-                'values' => $this->_taxCustomer->toOptionArray()
+                'values' => $this->_taxCustomer->toOptionArray(false)
             )
         );
 
diff --git a/app/code/Magento/Customer/Controller/Account.php b/app/code/Magento/Customer/Controller/Account.php
index 1c2bccde3782063d1077fdb3a53c3fbec995a4ac..dffcb758fab1f2951349ab5c4e3260d43f3cc316 100644
--- a/app/code/Magento/Customer/Controller/Account.php
+++ b/app/code/Magento/Customer/Controller/Account.php
@@ -26,19 +26,12 @@ namespace Magento\Customer\Controller;
 use Magento\Framework\App\RequestInterface;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
 use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
-use Magento\Customer\Service\V1\Data\Customer;
-use Magento\Framework\Exception\AuthenticationException;
-use Magento\Framework\Exception\EmailNotConfirmedException;
-use Magento\Framework\Exception\InputException;
-use Magento\Framework\Exception\NoSuchEntityException;
-use Magento\Framework\Exception\State\InvalidTransitionException;
-use Magento\Framework\Exception\StateException;
 
 /**
  * Customer account controller
  *
- * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class Account extends \Magento\Framework\App\Action\Action
@@ -69,122 +62,48 @@ class Account extends \Magento\Framework\App\Action\Action
     /** @var \Magento\Customer\Helper\Address */
     protected $_addressHelper;
 
-    /** @var \Magento\Customer\Helper\Data */
-    protected $_customerHelperData;
-
     /** @var \Magento\Framework\UrlFactory */
     protected $_urlFactory;
 
-    /** @var \Magento\Customer\Model\Metadata\FormFactory */
-    protected $_formFactory;
-
-    /** @var \Magento\Framework\Stdlib\String */
-    protected $string;
-
-    /** @var \Magento\Core\App\Action\FormKeyValidator */
-    protected $_formKeyValidator;
-
-    /** @var \Magento\Newsletter\Model\SubscriberFactory */
-    protected $_subscriberFactory;
-
     /** @var \Magento\Store\Model\StoreManagerInterface */
     protected $_storeManager;
 
     /** @var \Magento\Framework\App\Config\ScopeConfigInterface */
     protected $_scopeConfig;
 
-    /** @var \Magento\Core\Helper\Data */
-    protected $coreHelperData;
-
-    /** @var \Magento\Framework\Escaper */
-    protected $escaper;
-
     /** @var \Magento\Framework\App\State */
     protected $appState;
 
-    /** @var CustomerGroupServiceInterface */
-    protected $_groupService;
-
     /** @var CustomerAccountServiceInterface  */
     protected $_customerAccountService;
 
-    /** @var \Magento\Customer\Service\V1\Data\RegionBuilder */
-    protected $_regionBuilder;
-
-    /** @var \Magento\Customer\Service\V1\Data\AddressBuilder */
-    protected $_addressBuilder;
-
-    /** @var \Magento\Customer\Service\V1\Data\CustomerBuilder */
-    protected $_customerBuilder;
-
-    /** @var \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder */
-    protected $_customerDetailsBuilder;
-
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Customer\Model\Session $customerSession
      * @param \Magento\Customer\Helper\Address $addressHelper
-     * @param \Magento\Customer\Helper\Data $customerHelperData
      * @param \Magento\Framework\UrlFactory $urlFactory
-     * @param \Magento\Customer\Model\Metadata\FormFactory $formFactory
-     * @param \Magento\Framework\Stdlib\String $string
-     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
-     * @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Core\Helper\Data $coreHelperData
-     * @param \Magento\Framework\Escaper $escaper
      * @param \Magento\Framework\App\State $appState
-     * @param \Magento\Customer\Service\V1\CustomerGroupServiceInterface $customerGroupService
-     * @param \Magento\Customer\Service\V1\CustomerAccountServiceInterface $customerAccountService
-     * @param \Magento\Customer\Service\V1\Data\RegionBuilder $regionBuilder
-     * @param \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder
-     * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
-     * @param \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     * @param CustomerAccountServiceInterface $customerAccountService
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
         \Magento\Customer\Model\Session $customerSession,
         \Magento\Customer\Helper\Address $addressHelper,
-        \Magento\Customer\Helper\Data $customerHelperData,
         \Magento\Framework\UrlFactory $urlFactory,
-        \Magento\Customer\Model\Metadata\FormFactory $formFactory,
-        \Magento\Framework\Stdlib\String $string,
-        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
-        \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Core\Helper\Data $coreHelperData,
-        \Magento\Framework\Escaper $escaper,
         \Magento\Framework\App\State $appState,
-        CustomerGroupServiceInterface $customerGroupService,
-        CustomerAccountServiceInterface $customerAccountService,
-        \Magento\Customer\Service\V1\Data\RegionBuilder $regionBuilder,
-        \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder,
-        \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder,
-        \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder
+        CustomerAccountServiceInterface $customerAccountService
     ) {
         $this->_session = $customerSession;
         $this->_addressHelper = $addressHelper;
-        $this->_customerHelperData = $customerHelperData;
         $this->_urlFactory = $urlFactory;
-        $this->_formFactory = $formFactory;
-        $this->string = $string;
-        $this->_formKeyValidator = $formKeyValidator;
-        $this->_subscriberFactory = $subscriberFactory;
         $this->_storeManager = $storeManager;
         $this->_scopeConfig = $scopeConfig;
-        $this->coreHelperData = $coreHelperData;
-        $this->escaper = $escaper;
         $this->appState = $appState;
-        $this->_groupService = $customerGroupService;
         $this->_customerAccountService = $customerAccountService;
-        $this->_regionBuilder = $regionBuilder;
-        $this->_addressBuilder = $addressBuilder;
-        $this->_customerBuilder = $customerBuilder;
-        $this->_customerDetailsBuilder = $customerDetailsBuilder;
         parent::__construct($context);
     }
 
@@ -224,7 +143,7 @@ class Account extends \Magento\Framework\App\Action\Action
             parent::dispatch($request);
         }
 
-        $action = $this->getRequest()->getActionName();
+        $action = strtolower($this->getRequest()->getActionName());
         $pattern = '/^(' . implode('|', $this->_getAllowedActions()) . ')$/i';
 
         if (!preg_match($pattern, $action)) {
@@ -239,352 +158,6 @@ class Account extends \Magento\Framework\App\Action\Action
         return $result;
     }
 
-    /**
-     * Default customer account page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Account'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer login form page
-     *
-     * @return void
-     */
-    public function loginAction()
-    {
-        if ($this->_getSession()->isLoggedIn()) {
-            $this->_redirect('*/*/');
-            return;
-        }
-        $this->getResponse()->setHeader('Login-Required', 'true');
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Login post action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function loginPostAction()
-    {
-        if ($this->_getSession()->isLoggedIn() || !$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        if ($this->getRequest()->isPost()) {
-            $login = $this->getRequest()->getPost('login');
-            if (!empty($login['username']) && !empty($login['password'])) {
-                try {
-                    $customer = $this->_customerAccountService->authenticate($login['username'], $login['password']);
-                    $this->_getSession()->setCustomerDataAsLoggedIn($customer);
-                    $this->_getSession()->regenerateId();
-                } catch (EmailNotConfirmedException $e) {
-                    $value = $this->_customerHelperData->getEmailConfirmationUrl($login['username']);
-                    $message = __(
-                        'This account is not confirmed.' .
-                        ' <a href="%1">Click here</a> to resend confirmation email.',
-                        $value
-                    );
-                    $this->messageManager->addError($message);
-                    $this->_getSession()->setUsername($login['username']);
-                }
-                catch (AuthenticationException $e) {
-                    $message = __('Invalid login or password.');
-                    $this->messageManager->addError($message);
-                    $this->_getSession()->setUsername($login['username']);
-                } catch (\Exception $e) {
-                    // PA DSS violation: this exception log can disclose customer password
-                    // $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                    $this->messageManager->addError(__('There was an error validating the login and password.'));
-                }
-            } else {
-                $this->messageManager->addError(__('Login and password are required.'));
-            }
-        }
-
-        $this->_loginPostRedirect();
-    }
-
-    /**
-     * Define target URL and redirect customer after logging in
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    protected function _loginPostRedirect()
-    {
-        $lastCustomerId = $this->_getSession()->getLastCustomerId();
-        if (isset(
-            $lastCustomerId
-        ) && $this->_getSession()->isLoggedIn() && $lastCustomerId != $this->_getSession()->getId()
-        ) {
-            $this->_getSession()->unsBeforeAuthUrl()->setLastCustomerId($this->_getSession()->getId());
-        }
-        if (!$this->_getSession()->getBeforeAuthUrl() ||
-            $this->_getSession()->getBeforeAuthUrl() == $this->_storeManager->getStore()->getBaseUrl()
-        ) {
-            // Set default URL to redirect customer to
-            $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getAccountUrl());
-            // Redirect customer to the last page visited after logging in
-            if ($this->_getSession()->isLoggedIn()) {
-                if (!$this->_scopeConfig->isSetFlag(
-                    \Magento\Customer\Helper\Data::XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
-                ) {
-                    $referer = $this->getRequest()->getParam(\Magento\Customer\Helper\Data::REFERER_QUERY_PARAM_NAME);
-                    if ($referer) {
-                        $referer = $this->coreHelperData->urlDecode($referer);
-                        if ($this->_url->isOwnOriginUrl()) {
-                            $this->_getSession()->setBeforeAuthUrl($referer);
-                        }
-                    }
-                } elseif ($this->_getSession()->getAfterAuthUrl()) {
-                    $this->_getSession()->setBeforeAuthUrl($this->_getSession()->getAfterAuthUrl(true));
-                }
-            } else {
-                $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getLoginUrl());
-            }
-        } elseif ($this->_getSession()->getBeforeAuthUrl() == $this->_customerHelperData->getLogoutUrl()) {
-            $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getDashboardUrl());
-        } else {
-            if (!$this->_getSession()->getAfterAuthUrl()) {
-                $this->_getSession()->setAfterAuthUrl($this->_getSession()->getBeforeAuthUrl());
-            }
-            if ($this->_getSession()->isLoggedIn()) {
-                $this->_getSession()->setBeforeAuthUrl($this->_getSession()->getAfterAuthUrl(true));
-            }
-        }
-        $this->getResponse()->setRedirect($this->_getSession()->getBeforeAuthUrl(true));
-    }
-
-    /**
-     * Customer logout action
-     *
-     * @return void
-     */
-    public function logoutAction()
-    {
-        $lastCustomerId = $this->_getSession()->getId();
-        $this->_getSession()->logout()->setBeforeAuthUrl(
-            $this->_redirect->getRefererUrl()
-        )->setLastCustomerId(
-            $lastCustomerId
-        );
-
-        $this->_redirect('*/*/logoutSuccess');
-    }
-
-    /**
-     * Logout success page
-     *
-     * @return void
-     */
-    public function logoutSuccessAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Check whether registration is allowed
-     *
-     * @return bool
-     */
-    protected function isRegistrationAllowed()
-    {
-        return $this->_customerHelperData->isRegistrationAllowed();
-    }
-
-    /**
-     * Customer register form page
-     *
-     * @return void
-     */
-    public function createAction()
-    {
-        if ($this->_getSession()->isLoggedIn() || !$this->isRegistrationAllowed()) {
-            $this->_redirect('*/*');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create customer account action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function createPostAction()
-    {
-        if ($this->_getSession()->isLoggedIn() || !$this->isRegistrationAllowed()) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        if (!$this->getRequest()->isPost()) {
-            $url = $this->_createUrl()->getUrl('*/*/create', array('_secure' => true));
-            $this->getResponse()->setRedirect($this->_redirect->error($url));
-            return;
-        }
-
-        try {
-            $customer = $this->_extractCustomer('customer_account_create');
-            $address = $this->_extractAddress();
-            $addresses = is_null($address) ? array() : array($address);
-            $password = $this->getRequest()->getParam('password');
-            $redirectUrl = $this->_getSession()->getBeforeAuthUrl();
-            $customerDetails = $this->_customerDetailsBuilder
-                ->setCustomer($customer)
-                ->setAddresses($addresses)
-                ->create();
-            $customer = $this->_customerAccountService->createCustomer($customerDetails, $password, $redirectUrl);
-
-            if ($this->getRequest()->getParam('is_subscribed', false)) {
-                $this->_subscriberFactory->create()->subscribeCustomerById($customer->getId());
-            }
-
-            $this->_eventManager->dispatch(
-                'customer_register_success',
-                array('account_controller' => $this, 'customer' => $customer)
-            );
-
-            $confirmationStatus = $this->_customerAccountService->getConfirmationStatus($customer->getId());
-            if ($confirmationStatus === CustomerAccountServiceInterface::ACCOUNT_CONFIRMATION_REQUIRED) {
-                $email = $this->_customerHelperData->getEmailConfirmationUrl($customer->getEmail());
-                // @codingStandardsIgnoreStart
-                $this->messageManager->addSuccess(
-                    __(
-                        'Account confirmation is required. Please, check your email for the confirmation link. To resend the confirmation email please <a href="%1">click here</a>.',
-                        $email
-                    )
-                );
-                // @codingStandardsIgnoreEnd
-                $url = $this->_createUrl()->getUrl('*/*/index', array('_secure' => true));
-                $this->getResponse()->setRedirect($this->_redirect->success($url));
-            } else {
-                $this->_getSession()->setCustomerDataAsLoggedIn($customer);
-                $url = $this->_welcomeCustomer($customer);
-                $this->getResponse()->setRedirect($this->_redirect->success($url));
-            }
-            return;
-        } catch (StateException $e) {
-            $url = $this->_createUrl()->getUrl('customer/account/forgotpassword');
-            // @codingStandardsIgnoreStart
-            $message = __(
-                'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.',
-                $url
-            );
-            // @codingStandardsIgnoreEnd
-            $this->messageManager->addError($message);
-        } catch (InputException $e) {
-            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-            foreach ($e->getErrors() as $error) {
-                $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage()));
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Cannot save the customer.'));
-        }
-
-        $this->_getSession()->setCustomerFormData($this->getRequest()->getPost());
-        $defaultUrl = $this->_createUrl()->getUrl('*/*/create', array('_secure' => true));
-        $this->getResponse()->setRedirect($this->_redirect->error($defaultUrl));
-    }
-
-    /**
-     * Add address to customer during create account
-     *
-     * @return \Magento\Customer\Service\V1\Data\Address|null
-     */
-    protected function _extractAddress()
-    {
-        if (!$this->getRequest()->getPost('create_address')) {
-            return null;
-        }
-
-        $addressForm = $this->_createForm('customer_address', 'customer_register_address');
-        $allowedAttributes = $addressForm->getAllowedAttributes();
-
-        $addressData = array();
-
-        foreach ($allowedAttributes as $attribute) {
-            $attributeCode = $attribute->getAttributeCode();
-            $value = $this->getRequest()->getParam($attributeCode);
-            if (is_null($value)) {
-                continue;
-            }
-            switch ($attributeCode) {
-                case 'region_id':
-                    $this->_regionBuilder->setRegionId($value);
-                    break;
-                case 'region':
-                    $this->_regionBuilder->setRegion($value);
-                    break;
-                default:
-                    $addressData[$attributeCode] = $value;
-            }
-        }
-        $this->_addressBuilder->populateWithArray($addressData);
-        $this->_addressBuilder->setRegion($this->_regionBuilder->create());
-
-        $this->_addressBuilder->setDefaultBilling(
-            $this->getRequest()->getParam('default_billing', false)
-        )->setDefaultShipping(
-            $this->getRequest()->getParam('default_shipping', false)
-        );
-        return $this->_addressBuilder->create();
-    }
-
-    /**
-     * Extract customer entity from request
-     *
-     * @param string $formCode
-     * @return Customer
-     */
-    protected function _extractCustomer($formCode)
-    {
-        $customerForm = $this->_createForm('customer', $formCode);
-        $allowedAttributes = $customerForm->getAllowedAttributes();
-        $isGroupIdEmpty = true;
-        $customerData = array();
-        foreach ($allowedAttributes as $attribute) {
-            // confirmation in request param is the repeated password, not a confirmation code.
-            if ($attribute === 'confirmation') {
-                continue;
-            }
-            $attributeCode = $attribute->getAttributeCode();
-            if ($attributeCode == 'group_id') {
-                $isGroupIdEmpty = false;
-            }
-            $customerData[$attributeCode] = $this->getRequest()->getParam($attributeCode);
-        }
-        $this->_customerBuilder->populateWithArray($customerData);
-        $store = $this->_storeManager->getStore();
-        if ($isGroupIdEmpty) {
-            $this->_customerBuilder->setGroupId($this->_groupService->getDefaultGroup($store->getId())->getId());
-        }
-
-        $this->_customerBuilder->setWebsiteId($store->getWebsiteId());
-        $this->_customerBuilder->setStoreId($store->getId());
-
-        return $this->_customerBuilder->create();
-    }
-
     /**
      * Adds welcome message and returns success URL
      *
@@ -641,353 +214,6 @@ class Account extends \Magento\Framework\App\Action\Action
         }
     }
 
-    /**
-     * Load customer by id (try/catch in case if it throws exceptions)
-     *
-     * @param int $customerId
-     * @return \Magento\Customer\Service\V1\Data\Customer
-     * @throws \Exception
-     */
-    protected function _loadCustomerById($customerId)
-    {
-        try {
-            /** @var \Magento\Customer\Service\V1\Data\Customer $customer */
-            $customer = $this->_customerAccountService->getCustomer($customerId);
-            return $customer;
-        } catch (NoSuchEntityException $e) {
-            throw new \Exception(__('Wrong customer account specified.'));
-        }
-    }
-
-    /**
-     * Confirm customer account by id and confirmation key
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function confirmAction()
-    {
-        if ($this->_getSession()->isLoggedIn()) {
-            $this->_redirect('*/*/');
-            return;
-        }
-        try {
-            $customerId = $this->getRequest()->getParam('id', false);
-            $key = $this->getRequest()->getParam('key', false);
-            $backUrl = $this->getRequest()->getParam('back_url', false);
-            if (empty($customerId) || empty($key)) {
-                throw new \Exception(__('Bad request.'));
-            }
-
-            $customer = $this->_customerAccountService->activateCustomer($customerId, $key);
-
-            // log in and send greeting email, then die happy
-            $this->_getSession()->setCustomerDataAsLoggedIn($customer);
-            $successUrl = $this->_welcomeCustomer();
-            $this->getResponse()->setRedirect($this->_redirect->success($backUrl ? $backUrl : $successUrl));
-            return;
-        } catch (StateException $e) {
-            $this->messageManager->addException($e, __('This confirmation key is invalid or has expired.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('There was an error confirming the account'));
-        }
-        // die unhappy
-        $url = $this->_createUrl()->getUrl('*/*/index', array('_secure' => true));
-        $this->getResponse()->setRedirect($this->_redirect->error($url));
-        return;
-    }
-
-    /**
-     * Send confirmation link to specified email
-     *
-     * @return void
-     */
-    public function confirmationAction()
-    {
-        if ($this->_getSession()->isLoggedIn()) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        // try to confirm by email
-        $email = $this->getRequest()->getPost('email');
-        if ($email) {
-            try {
-                $this->_customerAccountService->resendConfirmation(
-                    $email,
-                    $this->_storeManager->getStore()->getWebsiteId()
-                );
-                $this->messageManager->addSuccess(__('Please, check your email for confirmation key.'));
-            } catch (InvalidTransitionException $e) {
-                $this->messageManager->addSuccess(__('This email does not require confirmation.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Wrong email.'));
-                $this->getResponse()->setRedirect(
-                    $this->_createUrl()->getUrl('*/*/*', array('email' => $email, '_secure' => true))
-                );
-                return;
-            }
-            $this->_getSession()->setUsername($email);
-            $this->getResponse()->setRedirect($this->_createUrl()->getUrl('*/*/index', array('_secure' => true)));
-            return;
-        }
-
-        // output form
-        $this->_view->loadLayout();
-
-        $this->_view->getLayout()->getBlock(
-            'accountConfirmation'
-        )->setEmail(
-            $this->getRequest()->getParam('email', $email)
-        );
-
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Forgot customer password page
-     *
-     * @return void
-     */
-    public function forgotPasswordAction()
-    {
-        $this->_view->loadLayout();
-
-        $this->_view->getLayout()->getBlock(
-            'forgotPassword'
-        )->setEmailValue(
-            $this->_getSession()->getForgottenEmail()
-        );
-        $this->_getSession()->unsForgottenEmail();
-
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Forgot customer password action
-     *
-     * @return void
-     */
-    public function forgotPasswordPostAction()
-    {
-        $email = (string)$this->getRequest()->getPost('email');
-        if ($email) {
-            if (!\Zend_Validate::is($email, 'EmailAddress')) {
-                $this->_getSession()->setForgottenEmail($email);
-                $this->messageManager->addError(__('Please correct the email address.'));
-                $this->_redirect('*/*/forgotpassword');
-                return;
-            }
-
-            try {
-                $this->_customerAccountService->initiatePasswordReset(
-                    $email,
-                    CustomerAccountServiceInterface::EMAIL_RESET
-                );
-            } catch (NoSuchEntityException $e) {
-                // Do nothing, we don't want anyone to use this action to determine which email accounts are registered.
-            } catch (\Exception $exception) {
-                $this->messageManager->addException($exception, __('Unable to send password reset email.'));
-                $this->_redirect('*/*/forgotpassword');
-                return;
-            }
-            $email = $this->escaper->escapeHtml($email);
-            // @codingStandardsIgnoreStart
-            $this->messageManager->addSuccess(
-                __(
-                    'If there is an account associated with %1 you will receive an email with a link to reset your password.',
-                    $email
-                )
-            );
-            // @codingStandardsIgnoreEnd
-            $this->_redirect('*/*/');
-            return;
-        } else {
-            $this->messageManager->addError(__('Please enter your email.'));
-            $this->_redirect('*/*/forgotpassword');
-            return;
-        }
-    }
-
-    /**
-     * Display reset forgotten password form
-     *
-     * User is redirected on this action when he clicks on the corresponding link in password reset confirmation email
-     *
-     * @return void
-     */
-    public function resetPasswordAction()
-    {
-        $this->_forward('createPassword');
-    }
-
-    /**
-     * Resetting password handler
-     *
-     * @return void
-     */
-    public function createPasswordAction()
-    {
-        $resetPasswordToken = (string)$this->getRequest()->getParam('token');
-        $customerId = (int)$this->getRequest()->getParam('id');
-        try {
-            $this->_customerAccountService->validateResetPasswordLinkToken($customerId, $resetPasswordToken);
-            $this->_view->loadLayout();
-            // Pass received parameters to the reset forgotten password form
-            $this->_view->getLayout()->getBlock(
-                'resetPassword'
-            )->setCustomerId(
-                $customerId
-            )->setResetPasswordLinkToken(
-                $resetPasswordToken
-            );
-            $this->_view->renderLayout();
-        } catch (\Exception $exception) {
-            $this->messageManager->addError(__('Your password reset link has expired.'));
-            $this->_redirect('*/*/forgotpassword');
-        }
-    }
-
-    /**
-     * Reset forgotten password
-     *
-     * Used to handle data received from reset forgotten password form
-     *
-     * @return void
-     */
-    public function resetPasswordPostAction()
-    {
-        $resetPasswordToken = (string)$this->getRequest()->getQuery('token');
-        $customerId = (int)$this->getRequest()->getQuery('id');
-        $password = (string)$this->getRequest()->getPost('password');
-        $passwordConfirmation = (string)$this->getRequest()->getPost('confirmation');
-
-        if ($password !== $passwordConfirmation) {
-            $this->messageManager->addError(__("New Password and Confirm New Password values didn't match."));
-            return;
-        }
-        if (iconv_strlen($password) <= 0) {
-            $this->messageManager->addError(__('New password field cannot be empty.'));
-            $this->_redirect('*/*/createpassword', array('id' => $customerId, 'token' => $resetPasswordToken));
-            return;
-        }
-
-        try {
-            $this->_customerAccountService->resetPassword($customerId, $resetPasswordToken, $password);
-            $this->messageManager->addSuccess(__('Your password has been updated.'));
-            $this->_redirect('*/*/login');
-            return;
-        } catch (\Exception $exception) {
-            $this->messageManager->addError(__('There was an error saving the new password.'));
-            $this->_redirect('*/*/createpassword', array('id' => $customerId, 'token' => $resetPasswordToken));
-            return;
-        }
-    }
-
-    /**
-     * Forgot customer account information page
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $block = $this->_view->getLayout()->getBlock('customer_edit');
-        if ($block) {
-            $block->setRefererUrl($this->_redirect->getRefererUrl());
-        }
-
-        $data = $this->_getSession()->getCustomerFormData(true);
-        $customerId = $this->_getSession()->getCustomerId();
-        $customerDataObject = $this->_customerAccountService->getCustomer($customerId);
-        if (!empty($data)) {
-            $customerDataObject = $this->_customerBuilder->mergeDataObjectWithArray($customerDataObject, $data);
-        }
-        $this->_getSession()->setCustomerData($customerDataObject);
-        $this->_getSession()->setChangePassword($this->getRequest()->getParam('changepass') == 1);
-
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Account Information'));
-        $this->_view->getLayout()->getBlock('messages')->setEscapeMessageFlag(true);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Change customer password action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function editPostAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_redirect('*/*/edit');
-            return;
-        }
-
-        if ($this->getRequest()->isPost()) {
-            $customerId = $this->_getSession()->getCustomerId();
-            $customer = $this->_extractCustomer('customer_account_edit');
-            $this->_customerBuilder->populate($customer);
-            $this->_customerBuilder->setId($customerId);
-            $customer = $this->_customerBuilder->create();
-
-            if ($this->getRequest()->getParam('change_password')) {
-                $currPass = $this->getRequest()->getPost('current_password');
-                $newPass = $this->getRequest()->getPost('password');
-                $confPass = $this->getRequest()->getPost('confirmation');
-
-                if (strlen($newPass)) {
-                    if ($newPass == $confPass) {
-                        try {
-                            $this->_customerAccountService->changePassword($customerId, $currPass, $newPass);
-                        } catch (AuthenticationException $e) {
-                            $this->messageManager->addError($e->getMessage());
-                        } catch (\Exception $e) {
-                            $this->messageManager->addException(
-                                $e,
-                                __('A problem was encountered trying to change password.')
-                            );
-                        }
-                    } else {
-                        $this->messageManager->addError(__('Confirm your new password'));
-                    }
-                } else {
-                    $this->messageManager->addError(__('New password field cannot be empty.'));
-                }
-            }
-
-            try {
-                $this->_customerDetailsBuilder->setCustomer($customer);
-                $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
-            } catch (AuthenticationException $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (InputException $e) {
-                $this->messageManager->addException($e, __('Invalid input'));
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('Cannot save the customer.') . $e->getMessage() . '<pre>' . $e->getTraceAsString() . '</pre>'
-                );
-            }
-
-            if ($this->messageManager->getMessages()->getCount() > 0) {
-                $this->_getSession()->setCustomerFormData($this->getRequest()->getPost());
-                $this->_redirect('*/*/edit');
-                return;
-            }
-
-            $this->messageManager->addSuccess(__('The account information has been saved.'));
-            $this->_redirect('customer/account');
-            return;
-        }
-
-        $this->_redirect('*/*/edit');
-    }
-
     /**
      * Check whether VAT ID validation is enabled
      *
@@ -1006,14 +232,4 @@ class Account extends \Magento\Framework\App\Action\Action
     {
         return $this->_urlFactory->create();
     }
-
-    /**
-     * @param string $entityType
-     * @param string $formCode
-     * @return \Magento\Customer\Model\Metadata\Form
-     */
-    protected function _createForm($entityType, $formCode)
-    {
-        return $this->_formFactory->create($entityType, $formCode);
-    }
 }
diff --git a/app/code/Magento/Customer/Controller/Account/Confirm.php b/app/code/Magento/Customer/Controller/Account/Confirm.php
new file mode 100644
index 0000000000000000000000000000000000000000..c931d7a4cb20c8a59c3bb9d524ae3954181ca824
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Confirm.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Framework\Exception\StateException;
+
+class Confirm extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Confirm customer account by id and confirmation key
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+        try {
+            $customerId = $this->getRequest()->getParam('id', false);
+            $key = $this->getRequest()->getParam('key', false);
+            $backUrl = $this->getRequest()->getParam('back_url', false);
+            if (empty($customerId) || empty($key)) {
+                throw new \Exception(__('Bad request.'));
+            }
+
+            $customer = $this->_customerAccountService->activateCustomer($customerId, $key);
+
+            // log in and send greeting email, then die happy
+            $this->_getSession()->setCustomerDataAsLoggedIn($customer);
+            $successUrl = $this->_welcomeCustomer();
+            $this->getResponse()->setRedirect($this->_redirect->success($backUrl ? $backUrl : $successUrl));
+            return;
+        } catch (StateException $e) {
+            $this->messageManager->addException($e, __('This confirmation key is invalid or has expired.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('There was an error confirming the account'));
+        }
+        // die unhappy
+        $url = $this->_createUrl()->getUrl('*/*/index', array('_secure' => true));
+        $this->getResponse()->setRedirect($this->_redirect->error($url));
+        return;
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Confirmation.php b/app/code/Magento/Customer/Controller/Account/Confirmation.php
new file mode 100644
index 0000000000000000000000000000000000000000..1465fb89ba5ccb549f438486837e66964fca65e7
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Confirmation.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Framework\Exception\State\InvalidTransitionException;
+
+class Confirmation extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Send confirmation link to specified email
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        // try to confirm by email
+        $email = $this->getRequest()->getPost('email');
+        if ($email) {
+            try {
+                $this->_customerAccountService->resendConfirmation(
+                    $email,
+                    $this->_storeManager->getStore()->getWebsiteId()
+                );
+                $this->messageManager->addSuccess(__('Please, check your email for confirmation key.'));
+            } catch (InvalidTransitionException $e) {
+                $this->messageManager->addSuccess(__('This email does not require confirmation.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Wrong email.'));
+                $this->getResponse()->setRedirect(
+                    $this->_createUrl()->getUrl('*/*/*', array('email' => $email, '_secure' => true))
+                );
+                return;
+            }
+            $this->_getSession()->setUsername($email);
+            $this->getResponse()->setRedirect($this->_createUrl()->getUrl('*/*/index', array('_secure' => true)));
+            return;
+        }
+
+        // output form
+        $this->_view->loadLayout();
+
+        $this->_view->getLayout()->getBlock(
+            'accountConfirmation'
+        )->setEmail(
+            $this->getRequest()->getParam('email', $email)
+        );
+
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Create.php b/app/code/Magento/Customer/Controller/Account/Create.php
new file mode 100644
index 0000000000000000000000000000000000000000..fcc57656561325acacf06dd1275014e49d04953c
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Create.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\App\Action\Action;
+
+class Create extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Customer\Helper\Data */
+    protected $customerHelper;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Customer\Helper\Address $addressHelper
+     * @param \Magento\Framework\UrlFactory $urlFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Customer\Helper\Data $customerHelper
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Customer\Helper\Address $addressHelper,
+        \Magento\Framework\UrlFactory $urlFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Customer\Helper\Data $customerHelper
+    ) {
+        $this->customerHelper = $customerHelper;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Customer register form page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn() || !$this->customerHelper->isRegistrationAllowed()) {
+            $this->_redirect('*/*');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/CreatePassword.php b/app/code/Magento/Customer/Controller/Account/CreatePassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..27386b7b9421532699ab70cd6acd62082f4a402d
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/CreatePassword.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class CreatePassword extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Resetting password handler
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $resetPasswordToken = (string)$this->getRequest()->getParam('token');
+        $customerId = (int)$this->getRequest()->getParam('id');
+        try {
+            $this->_customerAccountService->validateResetPasswordLinkToken($customerId, $resetPasswordToken);
+            $this->_view->loadLayout();
+            // Pass received parameters to the reset forgotten password form
+            $this->_view->getLayout()->getBlock(
+                'resetPassword'
+            )->setCustomerId(
+                $customerId
+            )->setResetPasswordLinkToken(
+                $resetPasswordToken
+            );
+            $this->_view->renderLayout();
+        } catch (\Exception $exception) {
+            $this->messageManager->addError(__('Your password reset link has expired.'));
+            $this->_redirect('*/*/forgotpassword');
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/CreatePost.php b/app/code/Magento/Customer/Controller/Account/CreatePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..df94a3471fa52cf20d3e2064427cc5213ba936b8
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/CreatePost.php
@@ -0,0 +1,253 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Framework\Exception\StateException;
+use Magento\Framework\Exception\InputException;
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class CreatePost extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Customer\Model\CustomerExtractor */
+    protected $customerExtractor;
+
+    /** @var \Magento\Customer\Model\Metadata\FormFactory */
+    protected $_formFactory;
+
+    /** @var \Magento\Newsletter\Model\SubscriberFactory */
+    protected $_subscriberFactory;
+
+    /** @var \Magento\Customer\Service\V1\Data\RegionBuilder */
+    protected $_regionBuilder;
+
+    /** @var \Magento\Customer\Service\V1\Data\AddressBuilder */
+    protected $_addressBuilder;
+
+    /** @var \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder */
+    protected $_customerDetailsBuilder;
+
+    /** @var \Magento\Customer\Helper\Data */
+    protected $_customerHelperData;
+
+    /** @var \Magento\Framework\Escaper */
+    protected $escaper;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Customer\Helper\Address $addressHelper
+     * @param \Magento\Framework\UrlFactory $urlFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Customer\Model\Metadata\FormFactory $formFactory
+     * @param \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory
+     * @param \Magento\Customer\Service\V1\Data\RegionBuilder $regionBuilder
+     * @param \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder
+     * @param \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder
+     * @param \Magento\Customer\Helper\Data $customerHelperData
+     * @param \Magento\Framework\Escaper $escaper
+     * @param \Magento\Customer\Model\CustomerExtractor $customerExtractor
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Customer\Helper\Address $addressHelper,
+        \Magento\Framework\UrlFactory $urlFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Customer\Model\Metadata\FormFactory $formFactory,
+        \Magento\Newsletter\Model\SubscriberFactory $subscriberFactory,
+        \Magento\Customer\Service\V1\Data\RegionBuilder $regionBuilder,
+        \Magento\Customer\Service\V1\Data\AddressBuilder $addressBuilder,
+        \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder,
+        \Magento\Customer\Helper\Data $customerHelperData,
+        \Magento\Framework\Escaper $escaper,
+        \Magento\Customer\Model\CustomerExtractor $customerExtractor
+    ) {
+        $this->_formFactory = $formFactory;
+        $this->_subscriberFactory = $subscriberFactory;
+        $this->_regionBuilder = $regionBuilder;
+        $this->_addressBuilder = $addressBuilder;
+        $this->_customerDetailsBuilder = $customerDetailsBuilder;
+        $this->_customerHelperData = $customerHelperData;
+        $this->escaper = $escaper;
+        $this->customerExtractor = $customerExtractor;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Add address to customer during create account
+     *
+     * @return \Magento\Customer\Service\V1\Data\Address|null
+     */
+    protected function _extractAddress()
+    {
+        if (!$this->getRequest()->getPost('create_address')) {
+            return null;
+        }
+
+        $addressForm = $this->_formFactory->create('customer_address', 'customer_register_address');
+        $allowedAttributes = $addressForm->getAllowedAttributes();
+
+        $addressData = array();
+
+        foreach ($allowedAttributes as $attribute) {
+            $attributeCode = $attribute->getAttributeCode();
+            $value = $this->getRequest()->getParam($attributeCode);
+            if (is_null($value)) {
+                continue;
+            }
+            switch ($attributeCode) {
+                case 'region_id':
+                    $this->_regionBuilder->setRegionId($value);
+                    break;
+                case 'region':
+                    $this->_regionBuilder->setRegion($value);
+                    break;
+                default:
+                    $addressData[$attributeCode] = $value;
+            }
+        }
+        $this->_addressBuilder->populateWithArray($addressData);
+        $this->_addressBuilder->setRegion($this->_regionBuilder->create());
+
+        $this->_addressBuilder->setDefaultBilling(
+            $this->getRequest()->getParam('default_billing', false)
+        )->setDefaultShipping(
+            $this->getRequest()->getParam('default_shipping', false)
+        );
+        return $this->_addressBuilder->create();
+    }
+
+    /**
+     * Is registration allowed
+     *
+     * @return bool
+     */
+    protected function isRegistrationAllowed()
+    {
+        return $this->_customerHelperData->isRegistrationAllowed();
+    }
+
+    /**
+     * Create customer account action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn() || !$this->isRegistrationAllowed()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        if (!$this->getRequest()->isPost()) {
+            $url = $this->_createUrl()->getUrl('*/*/create', array('_secure' => true));
+            $this->getResponse()->setRedirect($this->_redirect->error($url));
+            return;
+        }
+
+        try {
+            $customer = $this->customerExtractor->extract('customer_account_create', $this->_request);
+            $address = $this->_extractAddress();
+            $addresses = is_null($address) ? array() : array($address);
+            $password = $this->getRequest()->getParam('password');
+            $redirectUrl = $this->_getSession()->getBeforeAuthUrl();
+            $customerDetails = $this->_customerDetailsBuilder
+                ->setCustomer($customer)
+                ->setAddresses($addresses)
+                ->create();
+            $customer = $this->_customerAccountService->createCustomer($customerDetails, $password, $redirectUrl);
+
+            if ($this->getRequest()->getParam('is_subscribed', false)) {
+                $this->_subscriberFactory->create()->subscribeCustomerById($customer->getId());
+            }
+
+            $this->_eventManager->dispatch(
+                'customer_register_success',
+                array('account_controller' => $this, 'customer' => $customer)
+            );
+
+            $confirmationStatus = $this->_customerAccountService->getConfirmationStatus($customer->getId());
+            if ($confirmationStatus === CustomerAccountServiceInterface::ACCOUNT_CONFIRMATION_REQUIRED) {
+                $email = $this->_customerHelperData->getEmailConfirmationUrl($customer->getEmail());
+                // @codingStandardsIgnoreStart
+                $this->messageManager->addSuccess(
+                    __(
+                        'Account confirmation is required. Please, check your email for the confirmation link. To resend the confirmation email please <a href="%1">click here</a>.',
+                        $email
+                    )
+                );
+                // @codingStandardsIgnoreEnd
+                $url = $this->_createUrl()->getUrl('*/*/index', array('_secure' => true));
+                $this->getResponse()->setRedirect($this->_redirect->success($url));
+            } else {
+                $this->_getSession()->setCustomerDataAsLoggedIn($customer);
+                $url = $this->_welcomeCustomer($customer);
+                $this->getResponse()->setRedirect($this->_redirect->success($url));
+            }
+            return;
+        } catch (StateException $e) {
+            $url = $this->_createUrl()->getUrl('customer/account/forgotpassword');
+            // @codingStandardsIgnoreStart
+            $message = __(
+                'There is already an account with this email address. If you are sure that it is your email address, <a href="%1">click here</a> to get your password and access your account.',
+                $url
+            );
+            // @codingStandardsIgnoreEnd
+            $this->messageManager->addError($message);
+        } catch (InputException $e) {
+            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+            foreach ($e->getErrors() as $error) {
+                $this->messageManager->addError($this->escaper->escapeHtml($error->getMessage()));
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Cannot save the customer.'));
+        }
+
+        $this->_getSession()->setCustomerFormData($this->getRequest()->getPost());
+        $defaultUrl = $this->_createUrl()->getUrl('*/*/create', array('_secure' => true));
+        $this->getResponse()->setRedirect($this->_redirect->error($defaultUrl));
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Edit.php b/app/code/Magento/Customer/Controller/Account/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..022389054c8e4bcf51f192c9b68da9795d817fac
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Edit.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\App\Action\Context;
+use Magento\Customer\Model\Session;
+use Magento\Customer\Helper\Address as CustomerHelper;
+use Magento\Framework\UrlFactory;
+
+class Edit extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Customer\Service\V1\Data\CustomerBuilder */
+    protected $_customerBuilder;
+
+    /**
+     * @param Context $context
+     * @param Session $customerSession
+     * @param CustomerHelper $addressHelper
+     * @param UrlFactory $urlFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
+     */
+    public function __construct(
+        Context $context,
+        Session $customerSession,
+        CustomerHelper $addressHelper,
+        UrlFactory $urlFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
+    ) {
+        $this->_customerBuilder = $customerBuilder;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Forgot customer account information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $block = $this->_view->getLayout()->getBlock('customer_edit');
+        if ($block) {
+            $block->setRefererUrl($this->_redirect->getRefererUrl());
+        }
+
+        $data = $this->_getSession()->getCustomerFormData(true);
+        $customerId = $this->_getSession()->getCustomerId();
+        $customerDataObject = $this->_customerAccountService->getCustomer($customerId);
+        if (!empty($data)) {
+            $customerDataObject = $this->_customerBuilder->mergeDataObjectWithArray($customerDataObject, $data);
+        }
+        $this->_getSession()->setCustomerData($customerDataObject);
+        $this->_getSession()->setChangePassword($this->getRequest()->getParam('changepass') == 1);
+
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('Account Information'));
+        $this->_view->getLayout()->getBlock('messages')->setEscapeMessageFlag(true);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/EditPost.php b/app/code/Magento/Customer/Controller/Account/EditPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e59c352698740d1802c3910308f12bf3cd46e41
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/EditPost.php
@@ -0,0 +1,166 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\Exception\InputException;
+use Magento\Framework\Exception\AuthenticationException;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class EditPost extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Customer\Model\CustomerExtractor */
+    protected $customerExtractor;
+
+    /** @var \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder */
+    protected $_customerDetailsBuilder;
+
+    /** @var \Magento\Core\App\Action\FormKeyValidator */
+    protected $_formKeyValidator;
+
+    /** @var \Magento\Customer\Service\V1\Data\CustomerBuilder */
+    protected $_customerBuilder;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Customer\Helper\Address $addressHelper
+     * @param \Magento\Framework\UrlFactory $urlFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder
+     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
+     * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
+     * @param \Magento\Customer\Model\CustomerExtractor $customerExtractor
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Customer\Helper\Address $addressHelper,
+        \Magento\Framework\UrlFactory $urlFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Customer\Service\V1\Data\CustomerDetailsBuilder $customerDetailsBuilder,
+        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
+        \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder,
+        \Magento\Customer\Model\CustomerExtractor $customerExtractor
+    ) {
+        $this->_customerDetailsBuilder = $customerDetailsBuilder;
+        $this->_formKeyValidator = $formKeyValidator;
+        $this->_customerBuilder = $customerBuilder;
+        $this->customerExtractor = $customerExtractor;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Change customer password action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->_redirect('*/*/edit');
+            return;
+        }
+
+        if ($this->getRequest()->isPost()) {
+            $customerId = $this->_getSession()->getCustomerId();
+            $customer = $this->customerExtractor->extract('customer_account_edit', $this->_request);
+            $this->_customerBuilder->populate($customer);
+            $this->_customerBuilder->setId($customerId);
+            $customer = $this->_customerBuilder->create();
+
+            if ($this->getRequest()->getParam('change_password')) {
+                $currPass = $this->getRequest()->getPost('current_password');
+                $newPass = $this->getRequest()->getPost('password');
+                $confPass = $this->getRequest()->getPost('confirmation');
+
+                if (strlen($newPass)) {
+                    if ($newPass == $confPass) {
+                        try {
+                            $this->_customerAccountService->changePassword($customerId, $currPass, $newPass);
+                        } catch (AuthenticationException $e) {
+                            $this->messageManager->addError($e->getMessage());
+                        } catch (\Exception $e) {
+                            $this->messageManager->addException(
+                                $e,
+                                __('A problem was encountered trying to change password.')
+                            );
+                        }
+                    } else {
+                        $this->messageManager->addError(__('Confirm your new password'));
+                    }
+                } else {
+                    $this->messageManager->addError(__('New password field cannot be empty.'));
+                }
+            }
+
+            try {
+                $this->_customerDetailsBuilder->setCustomer($customer);
+                $this->_customerAccountService->updateCustomer($this->_customerDetailsBuilder->create());
+            } catch (AuthenticationException $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (InputException $e) {
+                $this->messageManager->addException($e, __('Invalid input'));
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('Cannot save the customer.') . $e->getMessage() . '<pre>' . $e->getTraceAsString() . '</pre>'
+                );
+            }
+
+            if ($this->messageManager->getMessages()->getCount() > 0) {
+                $this->_getSession()->setCustomerFormData($this->getRequest()->getPost());
+                $this->_redirect('*/*/edit');
+                return;
+            }
+
+            $this->messageManager->addSuccess(__('The account information has been saved.'));
+            $this->_redirect('customer/account');
+            return;
+        }
+
+        $this->_redirect('*/*/edit');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPassword.php b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..b080d8f0a7bacfde390b246fdd5b70244729fb4c
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/ForgotPassword.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class ForgotPassword extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Forgot customer password page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+
+        $this->_view->getLayout()->getBlock(
+            'forgotPassword'
+        )->setEmailValue(
+            $this->_getSession()->getForgottenEmail()
+        );
+        $this->_getSession()->unsForgottenEmail();
+
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/ForgotPasswordPost.php b/app/code/Magento/Customer/Controller/Account/ForgotPasswordPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..50a0e8622a019f173e307cc76f4265590048638f
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/ForgotPasswordPost.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\App\Action\Context;
+use Magento\Customer\Model\Session;
+use Magento\Customer\Helper\Address;
+use Magento\Framework\UrlFactory;
+use Magento\Store\Model\StoreManagerInterface;
+
+class ForgotPasswordPost extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Framework\Escaper */
+    protected $escaper;
+
+    /**
+     * @param Context $context
+     * @param Session $customerSession
+     * @param Address $addressHelper
+     * @param UrlFactory $urlFactory
+     * @param StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Framework\Escaper $escaper
+     */
+    public function __construct(
+        Context $context,
+        Session $customerSession,
+        Address $addressHelper,
+        UrlFactory $urlFactory,
+        StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Framework\Escaper $escaper
+    ) {
+        $this->escaper = $escaper;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Forgot customer password action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $email = (string)$this->getRequest()->getPost('email');
+        if ($email) {
+            if (!\Zend_Validate::is($email, 'EmailAddress')) {
+                $this->_getSession()->setForgottenEmail($email);
+                $this->messageManager->addError(__('Please correct the email address.'));
+                $this->_redirect('*/*/forgotpassword');
+                return;
+            }
+
+            try {
+                $this->_customerAccountService->initiatePasswordReset(
+                    $email,
+                    CustomerAccountServiceInterface::EMAIL_RESET
+                );
+            } catch (NoSuchEntityException $e) {
+                // Do nothing, we don't want anyone to use this action to determine which email accounts are registered.
+            } catch (\Exception $exception) {
+                $this->messageManager->addException($exception, __('Unable to send password reset email.'));
+                $this->_redirect('*/*/forgotpassword');
+                return;
+            }
+            $email = $this->escaper->escapeHtml($email);
+            // @codingStandardsIgnoreStart
+            $this->messageManager->addSuccess(
+                __(
+                    'If there is an account associated with %1 you will receive an email with a link to reset your password.',
+                    $email
+                )
+            );
+            // @codingStandardsIgnoreEnd
+            $this->_redirect('*/*/');
+            return;
+        } else {
+            $this->messageManager->addError(__('Please enter your email.'));
+            $this->_redirect('*/*/forgotpassword');
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Index.php b/app/code/Magento/Customer/Controller/Account/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..a4ac0da966df716aae547727e4c67b60ca3f999b
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class Index extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Default customer account page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Account'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Login.php b/app/code/Magento/Customer/Controller/Account/Login.php
new file mode 100644
index 0000000000000000000000000000000000000000..22e48cf61bc56a7e211334e7181614ab7e190172
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Login.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class Login extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Customer login form page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+        $this->getResponse()->setHeader('Login-Required', 'true');
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/LoginPost.php b/app/code/Magento/Customer/Controller/Account/LoginPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..33fc21bfa58fd297985d61beae9c7d63999226f9
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/LoginPost.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\Exception\EmailNotConfirmedException;
+use Magento\Framework\Exception\AuthenticationException;
+
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class LoginPost extends \Magento\Customer\Controller\Account
+{
+    /** @var \Magento\Core\Helper\Data */
+    protected $coreHelperData;
+
+    /** @var \Magento\Customer\Helper\Data */
+    protected $_customerHelperData;
+
+    /** @var \Magento\Core\App\Action\FormKeyValidator */
+    protected $_formKeyValidator;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Customer\Helper\Address $addressHelper
+     * @param \Magento\Framework\UrlFactory $urlFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Framework\App\State $appState
+     * @param CustomerAccountServiceInterface $customerAccountService
+     * @param \Magento\Core\Helper\Data $coreHelperData
+     * @param \Magento\Customer\Helper\Data $customerHelperData
+     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Customer\Helper\Address $addressHelper,
+        \Magento\Framework\UrlFactory $urlFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Framework\App\State $appState,
+        CustomerAccountServiceInterface $customerAccountService,
+        \Magento\Core\Helper\Data $coreHelperData,
+        \Magento\Customer\Helper\Data $customerHelperData,
+        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
+    ) {
+        $this->coreHelperData = $coreHelperData;
+        $this->_customerHelperData = $customerHelperData;
+        $this->_formKeyValidator = $formKeyValidator;
+        parent::__construct(
+            $context,
+            $customerSession,
+            $addressHelper,
+            $urlFactory,
+            $storeManager,
+            $scopeConfig,
+            $appState,
+            $customerAccountService
+        );
+    }
+
+    /**
+     * Define target URL and redirect customer after logging in
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    protected function _loginPostRedirect()
+    {
+        $lastCustomerId = $this->_getSession()->getLastCustomerId();
+        if (isset(
+            $lastCustomerId
+            ) && $this->_getSession()->isLoggedIn() && $lastCustomerId != $this->_getSession()->getId()
+        ) {
+            $this->_getSession()->unsBeforeAuthUrl()->setLastCustomerId($this->_getSession()->getId());
+        }
+        if (!$this->_getSession()->getBeforeAuthUrl() ||
+            $this->_getSession()->getBeforeAuthUrl() == $this->_storeManager->getStore()->getBaseUrl()
+        ) {
+            // Set default URL to redirect customer to
+            $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getAccountUrl());
+            // Redirect customer to the last page visited after logging in
+            if ($this->_getSession()->isLoggedIn()) {
+                if (!$this->_scopeConfig->isSetFlag(
+                    \Magento\Customer\Helper\Data::XML_PATH_CUSTOMER_STARTUP_REDIRECT_TO_DASHBOARD,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                )
+                ) {
+                    $referer = $this->getRequest()->getParam(\Magento\Customer\Helper\Data::REFERER_QUERY_PARAM_NAME);
+                    if ($referer) {
+                        $referer = $this->coreHelperData->urlDecode($referer);
+                        if ($this->_url->isOwnOriginUrl()) {
+                            $this->_getSession()->setBeforeAuthUrl($referer);
+                        }
+                    }
+                } elseif ($this->_getSession()->getAfterAuthUrl()) {
+                    $this->_getSession()->setBeforeAuthUrl($this->_getSession()->getAfterAuthUrl(true));
+                }
+            } else {
+                $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getLoginUrl());
+            }
+        } elseif ($this->_getSession()->getBeforeAuthUrl() == $this->_customerHelperData->getLogoutUrl()) {
+            $this->_getSession()->setBeforeAuthUrl($this->_customerHelperData->getDashboardUrl());
+        } else {
+            if (!$this->_getSession()->getAfterAuthUrl()) {
+                $this->_getSession()->setAfterAuthUrl($this->_getSession()->getBeforeAuthUrl());
+            }
+            if ($this->_getSession()->isLoggedIn()) {
+                $this->_getSession()->setBeforeAuthUrl($this->_getSession()->getAfterAuthUrl(true));
+            }
+        }
+        $this->getResponse()->setRedirect($this->_getSession()->getBeforeAuthUrl(true));
+    }
+
+    /**
+     * Login post action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        if ($this->_getSession()->isLoggedIn() || !$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        if ($this->getRequest()->isPost()) {
+            $login = $this->getRequest()->getPost('login');
+            if (!empty($login['username']) && !empty($login['password'])) {
+                try {
+                    $customer = $this->_customerAccountService->authenticate($login['username'], $login['password']);
+                    $this->_getSession()->setCustomerDataAsLoggedIn($customer);
+                    $this->_getSession()->regenerateId();
+                } catch (EmailNotConfirmedException $e) {
+                    $value = $this->_customerHelperData->getEmailConfirmationUrl($login['username']);
+                    $message = __(
+                        'This account is not confirmed.' .
+                        ' <a href="%1">Click here</a> to resend confirmation email.',
+                        $value
+                    );
+                    $this->messageManager->addError($message);
+                    $this->_getSession()->setUsername($login['username']);
+                }
+                catch (AuthenticationException $e) {
+                    $message = __('Invalid login or password.');
+                    $this->messageManager->addError($message);
+                    $this->_getSession()->setUsername($login['username']);
+                } catch (\Exception $e) {
+                    // PA DSS violation: this exception log can disclose customer password
+                    // $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    $this->messageManager->addError(__('There was an error validating the login and password.'));
+                }
+            } else {
+                $this->messageManager->addError(__('Login and password are required.'));
+            }
+        }
+
+        $this->_loginPostRedirect();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/Logout.php b/app/code/Magento/Customer/Controller/Account/Logout.php
new file mode 100644
index 0000000000000000000000000000000000000000..161693c7699432a7e426e1d2ae64b48909767fdd
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/Logout.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class Logout extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Customer logout action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $lastCustomerId = $this->_getSession()->getId();
+        $this->_getSession()->logout()->setBeforeAuthUrl(
+            $this->_redirect->getRefererUrl()
+        )->setLastCustomerId(
+            $lastCustomerId
+        );
+
+        $this->_redirect('*/*/logoutSuccess');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/LogoutSuccess.php b/app/code/Magento/Customer/Controller/Account/LogoutSuccess.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d604bba11e0c0e5f38624f7253ed190f4b4b75d
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/LogoutSuccess.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class LogoutSuccess extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Logout success page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/ResetPassword.php b/app/code/Magento/Customer/Controller/Account/ResetPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..a59a5b2732323a5022c58561aa4e1edea62a76a8
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/ResetPassword.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class ResetPassword extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Display reset forgotten password form
+     *
+     * User is redirected on this action when he clicks on the corresponding link in password reset confirmation email
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('createPassword');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..8129ba9a44e8b18ee734c414c2c10bb76a50ca2b
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Account/ResetPasswordPost.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class ResetPasswordPost extends \Magento\Customer\Controller\Account
+{
+    /**
+     * Reset forgotten password
+     *
+     * Used to handle data received from reset forgotten password form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $resetPasswordToken = (string)$this->getRequest()->getQuery('token');
+        $customerId = (int)$this->getRequest()->getQuery('id');
+        $password = (string)$this->getRequest()->getPost('password');
+        $passwordConfirmation = (string)$this->getRequest()->getPost('confirmation');
+
+        if ($password !== $passwordConfirmation) {
+            $this->messageManager->addError(__("New Password and Confirm New Password values didn't match."));
+            return;
+        }
+        if (iconv_strlen($password) <= 0) {
+            $this->messageManager->addError(__('New password field cannot be empty.'));
+            $this->_redirect('*/*/createPassword', array('id' => $customerId, 'token' => $resetPasswordToken));
+            return;
+        }
+
+        try {
+            $this->_customerAccountService->resetPassword($customerId, $resetPasswordToken, $password);
+            $this->messageManager->addSuccess(__('Your password has been updated.'));
+            $this->_redirect('*/*/login');
+            return;
+        } catch (\Exception $exception) {
+            $this->messageManager->addError(__('There was an error saving the new password.'));
+            $this->_redirect('*/*/createPassword', array('id' => $customerId, 'token' => $resetPasswordToken));
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address.php b/app/code/Magento/Customer/Controller/Address.php
index 5d0afa2fe4b84f95fc792269afedb62a1e2ac151..aa59d276f0769d445b58785be2a3eea2fc88049d 100644
--- a/app/code/Magento/Customer/Controller/Address.php
+++ b/app/code/Magento/Customer/Controller/Address.php
@@ -24,7 +24,6 @@
 namespace Magento\Customer\Controller;
 
 use Magento\Framework\App\RequestInterface;
-use Magento\Framework\Exception\InputException;
 
 /**
  * Customer address controller
@@ -117,156 +116,6 @@ class Address extends \Magento\Framework\App\Action\Action
         return parent::dispatch($request);
     }
 
-    /**
-     * Customer addresses list
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $addresses = $this->_addressService->getAddresses($this->_getSession()->getCustomerId());
-        if (count($addresses)) {
-            $this->_view->loadLayout();
-            $this->_view->getLayout()->initMessages();
-
-            $block = $this->_view->getLayout()->getBlock('address_book');
-            if ($block) {
-                $block->setRefererUrl($this->_redirect->getRefererUrl());
-            }
-            $this->_view->renderLayout();
-        } else {
-            $this->getResponse()->setRedirect($this->_buildUrl('*/*/new'));
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_forward('form');
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('form');
-    }
-
-    /**
-     * Address book form
-     *
-     * @return void
-     */
-    public function formAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
-        if ($navigationBlock) {
-            $navigationBlock->setActive('customer/address');
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Process address form save
-     *
-     * @return void
-     */
-    public function formPostAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        if (!$this->getRequest()->isPost()) {
-            $this->_getSession()->setAddressFormData($this->getRequest()->getPost());
-            $this->getResponse()->setRedirect($this->_redirect->error($this->_buildUrl('*/*/edit')));
-            return;
-        }
-        $customerId = $this->_getSession()->getCustomerId();
-        try {
-            $address = $this->_extractAddress();
-            $this->_addressService->saveAddresses($customerId, array($address));
-            $this->messageManager->addSuccess(__('The address has been saved.'));
-            $url = $this->_buildUrl('*/*/index', array('_secure' => true));
-            $this->getResponse()->setRedirect($this->_redirect->success($url));
-            return;
-        } catch (InputException $e) {
-            $this->messageManager->addError($e->getMessage());
-            foreach ($e->getErrors() as $error) {
-                $this->messageManager->addError($error->getMessage());
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Cannot save address.'));
-        }
-
-        $this->_getSession()->setAddressFormData($this->getRequest()->getPost());
-        $url = $this->_buildUrl('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
-        $this->getResponse()->setRedirect($this->_redirect->error($url));
-    }
-
-    /**
-     * Extract address from request
-     *
-     * @return \Magento\Customer\Service\V1\Data\Address
-     */
-    protected function _extractAddress()
-    {
-        $addressId = $this->getRequest()->getParam('id');
-        $existingAddressData = array();
-        if ($addressId) {
-            $existingAddress = $this->_addressService->getAddress($addressId);
-            if ($existingAddress->getId()) {
-                $existingAddressData = \Magento\Customer\Service\V1\Data\AddressConverter::toFlatArray(
-                    $existingAddress
-                );
-            }
-        }
-
-        /** @var \Magento\Customer\Model\Metadata\Form $addressForm */
-        $addressForm = $this->_formFactory->create('customer_address', 'customer_address_edit', $existingAddressData);
-        $addressData = $addressForm->extractData($this->getRequest());
-        $attributeValues = $addressForm->compactData($addressData);
-        $region = array('region_id' => $attributeValues['region_id'], 'region' => $attributeValues['region']);
-        unset($attributeValues['region'], $attributeValues['region_id']);
-        $attributeValues['region'] = $region;
-        return $this->_addressBuilder->populateWithArray(
-            array_merge($existingAddressData, $attributeValues)
-        )->setDefaultBilling(
-            $this->getRequest()->getParam('default_billing', false)
-        )->setDefaultShipping(
-            $this->getRequest()->getParam('default_shipping', false)
-        )->create();
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $addressId = $this->getRequest()->getParam('id', false);
-
-        if ($addressId) {
-            try {
-                $address = $this->_addressService->getAddress($addressId);
-                if ($address->getCustomerId() === $this->_getSession()->getCustomerId()) {
-                    $this->_addressService->deleteAddress($addressId);
-                    $this->messageManager->addSuccess(__('The address has been deleted.'));
-                } else {
-                    $this->messageManager->addError(__('An error occurred while deleting the address.'));
-                }
-            } catch (\Exception $other) {
-                $this->messageManager->addException($other, __('An error occurred while deleting the address.'));
-            }
-        }
-        $this->getResponse()->setRedirect($this->_buildUrl('*/*/index'));
-    }
-
     /**
      * @param string $route
      * @param array $params
diff --git a/app/code/Magento/Customer/Controller/Address/Delete.php b/app/code/Magento/Customer/Controller/Address/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..61d174f5d8abf0d248113cfa0a1d71e6b72ab6fa
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/Delete.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+class Delete extends \Magento\Customer\Controller\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $addressId = $this->getRequest()->getParam('id', false);
+
+        if ($addressId) {
+            try {
+                $address = $this->_addressService->getAddress($addressId);
+                if ($address->getCustomerId() === $this->_getSession()->getCustomerId()) {
+                    $this->_addressService->deleteAddress($addressId);
+                    $this->messageManager->addSuccess(__('The address has been deleted.'));
+                } else {
+                    $this->messageManager->addError(__('An error occurred while deleting the address.'));
+                }
+            } catch (\Exception $other) {
+                $this->messageManager->addException($other, __('An error occurred while deleting the address.'));
+            }
+        }
+        $this->getResponse()->setRedirect($this->_buildUrl('*/*/index'));
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address/Edit.php b/app/code/Magento/Customer/Controller/Address/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..30820495661e31858701a0985a643398d9966eb7
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/Edit.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+class Edit extends \Magento\Customer\Controller\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('form');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address/Form.php b/app/code/Magento/Customer/Controller/Address/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..c36ef8c8af975ee7aa567df73ac06c648155ff35
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/Form.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+class Form extends \Magento\Customer\Controller\Address
+{
+    /**
+     * Address book form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
+        if ($navigationBlock) {
+            $navigationBlock->setActive('customer/address');
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address/FormPost.php b/app/code/Magento/Customer/Controller/Address/FormPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e8f0d8a1b3df0bc8b1ca45e511741b294d5dcfb
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/FormPost.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+use Magento\Framework\Exception\InputException;
+
+class FormPost extends \Magento\Customer\Controller\Address
+{
+    /**
+     * Extract address from request
+     *
+     * @return \Magento\Customer\Service\V1\Data\Address
+     */
+    protected function _extractAddress()
+    {
+        $addressId = $this->getRequest()->getParam('id');
+        $existingAddressData = array();
+        if ($addressId) {
+            $existingAddress = $this->_addressService->getAddress($addressId);
+            if ($existingAddress->getId()) {
+                $existingAddressData = \Magento\Customer\Service\V1\Data\AddressConverter::toFlatArray(
+                    $existingAddress
+                );
+            }
+        }
+
+        /** @var \Magento\Customer\Model\Metadata\Form $addressForm */
+        $addressForm = $this->_formFactory->create('customer_address', 'customer_address_edit', $existingAddressData);
+        $addressData = $addressForm->extractData($this->getRequest());
+        $attributeValues = $addressForm->compactData($addressData);
+        $region = array('region_id' => $attributeValues['region_id'], 'region' => $attributeValues['region']);
+        unset($attributeValues['region'], $attributeValues['region_id']);
+        $attributeValues['region'] = $region;
+        return $this->_addressBuilder->populateWithArray(
+            array_merge($existingAddressData, $attributeValues)
+        )->setDefaultBilling(
+            $this->getRequest()->getParam('default_billing', false)
+        )->setDefaultShipping(
+            $this->getRequest()->getParam('default_shipping', false)
+        )->create();
+    }
+
+    /**
+     * Process address form save
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        if (!$this->getRequest()->isPost()) {
+            $this->_getSession()->setAddressFormData($this->getRequest()->getPost());
+            $this->getResponse()->setRedirect($this->_redirect->error($this->_buildUrl('*/*/edit')));
+            return;
+        }
+        $customerId = $this->_getSession()->getCustomerId();
+        try {
+            $address = $this->_extractAddress();
+            $this->_addressService->saveAddresses($customerId, array($address));
+            $this->messageManager->addSuccess(__('The address has been saved.'));
+            $url = $this->_buildUrl('*/*/index', array('_secure' => true));
+            $this->getResponse()->setRedirect($this->_redirect->success($url));
+            return;
+        } catch (InputException $e) {
+            $this->messageManager->addError($e->getMessage());
+            foreach ($e->getErrors() as $error) {
+                $this->messageManager->addError($error->getMessage());
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Cannot save address.'));
+        }
+
+        $this->_getSession()->setAddressFormData($this->getRequest()->getPost());
+        $url = $this->_buildUrl('*/*/edit', array('id' => $this->getRequest()->getParam('id')));
+        $this->getResponse()->setRedirect($this->_redirect->error($url));
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address/Index.php b/app/code/Magento/Customer/Controller/Address/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..05d12effa431f3a6716723ffeebb0e68d1518811
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/Index.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+class Index extends \Magento\Customer\Controller\Address
+{
+    /**
+     * Customer addresses list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $addresses = $this->_addressService->getAddresses($this->_getSession()->getCustomerId());
+        if (count($addresses)) {
+            $this->_view->loadLayout();
+            $this->_view->getLayout()->initMessages();
+
+            $block = $this->_view->getLayout()->getBlock('address_book');
+            if ($block) {
+                $block->setRefererUrl($this->_redirect->getRefererUrl());
+            }
+            $this->_view->renderLayout();
+        } else {
+            $this->getResponse()->setRedirect($this->_buildUrl('*/*/new'));
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Address/NewAction.php b/app/code/Magento/Customer/Controller/Address/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..58aea41a70416981a9f4e6f20d0a79f37c020827
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Address/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Address;
+
+class NewAction extends \Magento\Customer\Controller\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('form');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart.php b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart.php
index 97f919dd39400283985fc958aa7abd06e0626d93..611cd4975cbd59c5f8d710e0a9bf4dc4bcfc5aa4 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart.php
@@ -85,69 +85,6 @@ class Cart extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Ajax handler to response configuration fieldset of composite product in customer's cart
-     *
-     * @return void
-     */
-    public function configureAction()
-    {
-        $configureResult = new \Magento\Framework\Object();
-        try {
-            $this->_initData();
-
-            $quoteItem = $this->_quoteItem;
-
-            $optionCollection = $this->_objectManager->create(
-                'Magento\Sales\Model\Quote\Item\Option'
-            )->getCollection()->addItemFilter(
-                $quoteItem
-            );
-            $quoteItem->setOptions($optionCollection->getOptionsByItem($quoteItem));
-
-            $configureResult->setOk(true);
-            $configureResult->setProductId($quoteItem->getProductId());
-            $configureResult->setBuyRequest($quoteItem->getBuyRequest());
-            $configureResult->setCurrentStoreId($quoteItem->getStoreId());
-            $configureResult->setCurrentCustomerId($this->_customerId);
-        } catch (\Exception $e) {
-            $configureResult->setError(true);
-            $configureResult->setMessage($e->getMessage());
-        }
-
-        $this->_objectManager->get(
-            'Magento\Catalog\Helper\Product\Composite'
-        )->renderConfigureResult(
-            $configureResult
-        );
-    }
-
-    /**
-     * IFrame handler for submitted configuration for quote item
-     *
-     * @return void
-     */
-    public function updateAction()
-    {
-        $updateResult = new \Magento\Framework\Object();
-        try {
-            $this->_initData();
-
-            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
-            $this->_quote->updateItem($this->_quoteItem->getId(), $buyRequest);
-            $this->_quote->collectTotals()->save();
-
-            $updateResult->setOk(true);
-        } catch (\Exception $e) {
-            $updateResult->setError(true);
-            $updateResult->setMessage($e->getMessage());
-        }
-
-        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
-        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
-        $this->_redirect('catalog/product/showUpdateResult');
-    }
-
     /**
      * Check the permission to Manage Customers
      *
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Configure.php b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Configure.php
new file mode 100644
index 0000000000000000000000000000000000000000..4d791ea005d18ce8a405f5ca31f9c3290b1abe4d
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Configure.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Cart\Product\Composite\Cart;
+
+class Configure extends \Magento\Customer\Controller\Adminhtml\Cart\Product\Composite\Cart
+{
+    /**
+     * Ajax handler to response configuration fieldset of composite product in customer's cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $configureResult = new \Magento\Framework\Object();
+        try {
+            $this->_initData();
+
+            $quoteItem = $this->_quoteItem;
+
+            $optionCollection = $this->_objectManager->create(
+                'Magento\Sales\Model\Quote\Item\Option'
+            )->getCollection()->addItemFilter(
+                $quoteItem
+            );
+            $quoteItem->setOptions($optionCollection->getOptionsByItem($quoteItem));
+
+            $configureResult->setOk(true);
+            $configureResult->setProductId($quoteItem->getProductId());
+            $configureResult->setBuyRequest($quoteItem->getBuyRequest());
+            $configureResult->setCurrentStoreId($quoteItem->getStoreId());
+            $configureResult->setCurrentCustomerId($this->_customerId);
+        } catch (\Exception $e) {
+            $configureResult->setError(true);
+            $configureResult->setMessage($e->getMessage());
+        }
+
+        $this->_objectManager->get(
+            'Magento\Catalog\Helper\Product\Composite'
+        )->renderConfigureResult(
+            $configureResult
+        );
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Update.php b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Update.php
new file mode 100644
index 0000000000000000000000000000000000000000..90dc3a248d971ab71be0fa7bed503c2660cfa585
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Cart/Product/Composite/Cart/Update.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Cart\Product\Composite\Cart;
+
+class Update extends \Magento\Customer\Controller\Adminhtml\Cart\Product\Composite\Cart
+{
+    /**
+     * IFrame handler for submitted configuration for quote item
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $updateResult = new \Magento\Framework\Object();
+        try {
+            $this->_initData();
+
+            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
+            $this->_quote->updateItem($this->_quoteItem->getId(), $buyRequest);
+            $this->_quote->collectTotals()->save();
+
+            $updateResult->setOk(true);
+        } catch (\Exception $e) {
+            $updateResult->setError(true);
+            $updateResult->setMessage($e->getMessage());
+        }
+
+        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
+        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
+        $this->_redirect('catalog/product/showUpdateResult');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group.php b/app/code/Magento/Customer/Controller/Adminhtml/Group.php
index f14992ebf56a37bdbb1448939009ceea9f08e1cf..7b344f2ae565efe6c39575f199ff932862fa02ab 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Group.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group.php
@@ -23,12 +23,8 @@
  */
 namespace Magento\Customer\Controller\Adminhtml;
 
-use Magento\Customer\Controller\RegistryConstants;
-use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
-use Magento\Customer\Service\V1\Data\CustomerGroup;
 use Magento\Customer\Service\V1\Data\CustomerGroupBuilder;
-use Magento\Framework\Exception\InputException;
 
 /**
  * Customer groups controller
@@ -72,149 +68,6 @@ class Group extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Initialize current group and set it in the registry.
-     *
-     * @return int
-     */
-    protected function _initGroup()
-    {
-        $this->_title->add(__('Customer Groups'));
-
-        $groupId = $this->getRequest()->getParam('id');
-        $this->_coreRegistry->register(RegistryConstants::CURRENT_GROUP_ID, $groupId);
-
-        return $groupId;
-    }
-
-    /**
-     * Customer groups list.
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Customer Groups'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Customer::customer_group');
-        $this->_addBreadcrumb(__('Customers'), __('Customers'));
-        $this->_addBreadcrumb(__('Customer Groups'), __('Customer Groups'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Edit or create customer group.
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $groupId = $this->_initGroup();
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Customer::customer_group');
-        $this->_addBreadcrumb(__('Customers'), __('Customers'));
-        $this->_addBreadcrumb(__('Customer Groups'), __('Customer Groups'), $this->getUrl('customer/group'));
-
-        if (is_null($groupId)) {
-            $this->_addBreadcrumb(__('New Group'), __('New Customer Groups'));
-            $this->_title->add(__('New Customer Group'));
-        } else {
-            $this->_addBreadcrumb(__('Edit Group'), __('Edit Customer Groups'));
-            $this->_title->add($this->_groupService->getGroup($groupId)->getCode());
-        }
-
-        $this->_view->getLayout()->addBlock(
-            'Magento\Customer\Block\Adminhtml\Group\Edit',
-            'group',
-            'content'
-        )->setEditMode(
-            (bool)$groupId
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Edit customer group action. Forward to new action.
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_forward('new');
-    }
-
-    /**
-     * Create or save customer group.
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $taxClass = (int)$this->getRequest()->getParam('tax_class');
-
-        /** @var CustomerGroup $customerGroup */
-        $customerGroup = null;
-        if ($taxClass) {
-            $id = $this->getRequest()->getParam('id');
-            try {
-                if (!is_null($id)) {
-                    $this->_customerGroupBuilder->populate($this->_groupService->getGroup((int)$id));
-                }
-                $customerGroupCode = (string)$this->getRequest()->getParam('code');
-                if (empty($customerGroupCode)) {
-                    $customerGroupCode = null;
-                }
-                $this->_customerGroupBuilder->setCode($customerGroupCode);
-                $this->_customerGroupBuilder->setTaxClassId($taxClass);
-                $customerGroup = $this->_customerGroupBuilder->create();
-
-                $id = $this->_groupService->saveGroup($customerGroup);
-                $this->messageManager->addSuccess(__('The customer group has been saved.'));
-                $this->getResponse()->setRedirect($this->getUrl('customer/group'));
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                if ($customerGroup != null) {
-                    $this->storeCustomerGroupDataToSession($customerGroup->__toArray());
-                }
-                $this->getResponse()->setRedirect($this->getUrl('customer/group/edit', array('id' => $id)));
-                return;
-            }
-        } else {
-            $this->_forward('new');
-        }
-    }
-
-    /**
-     * Delete customer group.
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            try {
-                $this->_groupService->deleteGroup($id);
-                $this->messageManager->addSuccess(__('The customer group has been deleted.'));
-                $this->getResponse()->setRedirect($this->getUrl('customer/group'));
-                return;
-            } catch (NoSuchEntityException $e) {
-                $this->messageManager->addError(__('The customer group no longer exists.'));
-                $this->getResponse()->setRedirect($this->getUrl('customer/*/'));
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->getResponse()->setRedirect($this->getUrl('customer/group/edit', array('id' => $id)));
-                return;
-            }
-        }
-        $this->_redirect('customer/group');
-    }
-
     /**
      * Determine if authorized to perform group actions.
      *
@@ -224,19 +77,4 @@ class Group extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Customer::group');
     }
-
-    /**
-     * Store Customer Group Data to session
-     *
-     * @param array $customerGroupData
-     * @return void
-     */
-    protected function storeCustomerGroupDataToSession($customerGroupData)
-    {
-        if (array_key_exists('code', $customerGroupData)) {
-            $customerGroupData['customer_group_code'] = $customerGroupData['code'];
-            unset($customerGroupData['code']);
-        }
-        $this->_getSession()->setCustomerGroupData($customerGroupData);
-    }
 }
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..58589f677929be7c9612f7df0e093d06a4dc0e32
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Delete.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Group;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class Delete extends \Magento\Customer\Controller\Adminhtml\Group
+{
+    /**
+     * Delete customer group.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            try {
+                $this->_groupService->deleteGroup($id);
+                $this->messageManager->addSuccess(__('The customer group has been deleted.'));
+                $this->getResponse()->setRedirect($this->getUrl('customer/group'));
+                return;
+            } catch (NoSuchEntityException $e) {
+                $this->messageManager->addError(__('The customer group no longer exists.'));
+                $this->getResponse()->setRedirect($this->getUrl('customer/*/'));
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->getResponse()->setRedirect($this->getUrl('customer/group/edit', array('id' => $id)));
+                return;
+            }
+        }
+        $this->_redirect('customer/group');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Edit.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..2a8403661e629ee95097eaa069b988cb27683602
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Edit.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Group;
+
+class Edit extends \Magento\Customer\Controller\Adminhtml\Group
+{
+    /**
+     * Edit customer group action. Forward to new action.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('new');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..62ef1a1b4d1c16f60a641c17f81a93bf912d06d4
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Index.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Group;
+
+class Index extends \Magento\Customer\Controller\Adminhtml\Group
+{
+    /**
+     * Customer groups list.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Groups'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Customer::customer_group');
+        $this->_addBreadcrumb(__('Customers'), __('Customers'));
+        $this->_addBreadcrumb(__('Customer Groups'), __('Customer Groups'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/NewAction.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2a84204e53d12b8b579febc1f70c641fb61fa49
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/NewAction.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Group;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class NewAction extends \Magento\Customer\Controller\Adminhtml\Group
+{
+    /**
+     * Initialize current group and set it in the registry.
+     *
+     * @return int
+     */
+    protected function _initGroup()
+    {
+        $this->_title->add(__('Customer Groups'));
+
+        $groupId = $this->getRequest()->getParam('id');
+        $this->_coreRegistry->register(RegistryConstants::CURRENT_GROUP_ID, $groupId);
+
+        return $groupId;
+    }
+
+    /**
+     * Edit or create customer group.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $groupId = $this->_initGroup();
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Customer::customer_group');
+        $this->_addBreadcrumb(__('Customers'), __('Customers'));
+        $this->_addBreadcrumb(__('Customer Groups'), __('Customer Groups'), $this->getUrl('customer/group'));
+
+        if (is_null($groupId)) {
+            $this->_addBreadcrumb(__('New Group'), __('New Customer Groups'));
+            $this->_title->add(__('New Customer Group'));
+        } else {
+            $this->_addBreadcrumb(__('Edit Group'), __('Edit Customer Groups'));
+            $this->_title->add($this->_groupService->getGroup($groupId)->getCode());
+        }
+
+        $this->_view->getLayout()->addBlock(
+            'Magento\Customer\Block\Adminhtml\Group\Edit',
+            'group',
+            'content'
+        )->setEditMode(
+            (bool)$groupId
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..db5df3518de7de578b318b1000d72a08a17cc63e
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Group/Save.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Group;
+
+use Magento\Customer\Service\V1\Data\CustomerGroup;
+
+class Save extends \Magento\Customer\Controller\Adminhtml\Group
+{
+    /**
+     * Store Customer Group Data to session
+     *
+     * @param array $customerGroupData
+     * @return void
+     */
+    protected function storeCustomerGroupDataToSession($customerGroupData)
+    {
+        if (array_key_exists('code', $customerGroupData)) {
+            $customerGroupData['customer_group_code'] = $customerGroupData['code'];
+            unset($customerGroupData['code']);
+        }
+        $this->_getSession()->setCustomerGroupData($customerGroupData);
+    }
+
+    /**
+     * Create or save customer group.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $taxClass = (int)$this->getRequest()->getParam('tax_class');
+
+        /** @var CustomerGroup $customerGroup */
+        $customerGroup = null;
+        if ($taxClass) {
+            $id = $this->getRequest()->getParam('id');
+            try {
+                if (!is_null($id)) {
+                    $this->_customerGroupBuilder->populate($this->_groupService->getGroup((int)$id));
+                }
+                $customerGroupCode = (string)$this->getRequest()->getParam('code');
+                if (empty($customerGroupCode)) {
+                    $customerGroupCode = null;
+                }
+                $this->_customerGroupBuilder->setCode($customerGroupCode);
+                $this->_customerGroupBuilder->setTaxClassId($taxClass);
+                $customerGroup = $this->_customerGroupBuilder->create();
+
+                $id = $this->_groupService->saveGroup($customerGroup);
+                $this->messageManager->addSuccess(__('The customer group has been saved.'));
+                $this->getResponse()->setRedirect($this->getUrl('customer/group'));
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                if ($customerGroup != null) {
+                    $this->storeCustomerGroupDataToSession($customerGroup->__toArray());
+                }
+                $this->getResponse()->setRedirect($this->getUrl('customer/group/edit', array('id' => $id)));
+                return;
+            }
+        } else {
+            $this->_forward('new');
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Index.php
index 3f943deeb082b92468369137f575ede1bdaa8ecd..3485fa2bd1eb0b2f38e016910b4dfa8101f2ad76 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index.php
@@ -23,19 +23,13 @@
  */
 namespace Magento\Customer\Controller\Adminhtml;
 
-use Magento\Framework\App\Action\NotFoundException;
-use Magento\Customer\Controller\RegistryConstants;
-use Magento\Customer\Service\V1\Data\Customer;
 use Magento\Customer\Service\V1\Data\CustomerBuilder;
 use Magento\Customer\Service\V1\Data\AddressBuilder;
 use Magento\Customer\Service\V1\Data\CustomerDetailsBuilder;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
 use Magento\Customer\Service\V1\CustomerAddressServiceInterface;
-use Magento\Framework\Exception\LocalizedException;
-use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Message\Error;
-use Magento\Customer\Service\V1\CustomerMetadataServiceInterface as CustomerMetadata;
-use Magento\Customer\Service\V1\Data\AddressConverter;
+use Magento\Customer\Controller\RegistryConstants;
 
 /**
  * Class Index
@@ -43,6 +37,7 @@ use Magento\Customer\Service\V1\Data\AddressConverter;
  * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.NumberOfChildren)
  */
 class Index extends \Magento\Backend\App\Action
 {
@@ -183,338 +178,6 @@ class Index extends \Magento\Backend\App\Action
         return $customerId;
     }
 
-    /**
-     * Customers list action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Customers'));
-
-        if ($this->getRequest()->getQuery('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-        $this->_view->loadLayout();
-
-        /**
-         * Set active menu item
-         */
-        $this->_setActiveMenu('Magento_Customer::customer_manage');
-
-        /**
-         * Add breadcrumb item
-         */
-        $this->_addBreadcrumb(__('Customers'), __('Customers'));
-        $this->_addBreadcrumb(__('Manage Customers'), __('Manage Customers'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer grid action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer edit action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    public function editAction()
-    {
-        $customerId = $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Customer::customer_manage');
-
-        $customerData = array();
-        $customerData['account'] = array();
-        $customerData['address'] = array();
-        $customer = null;
-        $isExistingCustomer = (bool)$customerId;
-        if ($isExistingCustomer) {
-            try {
-                $customer = $this->_customerAccountService->getCustomer($customerId);
-                $customerData['account'] = \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($customer);
-                $customerData['account']['id'] = $customerId;
-                try {
-                    $addresses = $this->_addressService->getAddresses($customerId);
-                    foreach ($addresses as $address) {
-                        $customerData['address'][$address->getId()] = AddressConverter::toFlatArray($address);
-                        $customerData['address'][$address->getId()]['id'] = $address->getId();
-                    }
-                } catch (NoSuchEntityException $e) {
-                    //do nothing
-                }
-            } catch (NoSuchEntityException $e) {
-                $this->messageManager->addException($e, __('An error occurred while editing the customer.'));
-                $this->_redirect('customer/*/index');
-                return;
-            }
-        }
-        $customerData['customer_id'] = $customerId;
-
-        // set entered data if was error when we do save
-        $data = $this->_getSession()->getCustomerData(true);
-
-        // restore data from SESSION
-        if ($data && (!isset(
-                $data['customer_id']
-                ) || isset(
-                $data['customer_id']
-                ) && $data['customer_id'] == $customerId)
-        ) {
-            $request = clone $this->getRequest();
-            $request->setParams($data);
-
-            if (isset($data['account']) && is_array($data['account'])) {
-                $customerForm = $this->_formFactory->create(
-                    'customer',
-                    'adminhtml_customer',
-                    $customerData['account'],
-                    true
-                );
-                $formData = $customerForm->extractData($request, 'account');
-                $customerData['account'] = $customerForm->restoreData($formData);
-                $customer = $this->_customerBuilder->populateWithArray($customerData['account'])->create();
-            }
-
-            if (isset($data['address']) && is_array($data['address'])) {
-                foreach (array_keys($data['address']) as $addressId) {
-                    if ($addressId == '_template_') {
-                        continue;
-                    }
-
-                    try {
-                        $address = $this->_addressService->getAddress($addressId);
-                        if (!empty($customerId) && $address->getCustomerId() == $customerId) {
-                            $this->_addressBuilder->populate($address);
-                        }
-                    } catch (NoSuchEntityException $e) {
-                        $this->_addressBuilder->setId($addressId);
-                    }
-                    if (!empty($customerId)) {
-                        $this->_addressBuilder->setCustomerId($customerId);
-                    }
-                    $this->_addressBuilder->setDefaultBilling(
-                        !empty($data['account'][Customer::DEFAULT_BILLING]) &&
-                        $data['account'][Customer::DEFAULT_BILLING] == $addressId
-                    );
-                    $this->_addressBuilder->setDefaultShipping(
-                        !empty($data['account'][Customer::DEFAULT_SHIPPING]) &&
-                        $data['account'][Customer::DEFAULT_SHIPPING] == $addressId
-                    );
-                    $address = $this->_addressBuilder->create();
-                    $requestScope = sprintf('address/%s', $addressId);
-                    $addressForm = $this->_formFactory->create(
-                        'customer_address',
-                        'adminhtml_customer_address',
-                        AddressConverter::toFlatArray($address)
-                    );
-                    $formData = $addressForm->extractData($request, $requestScope);
-                    $customerData['address'][$addressId] = $addressForm->restoreData($formData);
-                    $customerData['address'][$addressId]['id'] = $addressId;
-                }
-            }
-        }
-
-        $this->_getSession()->setCustomerData($customerData);
-
-        if ($isExistingCustomer) {
-            $this->_title->add($this->_viewHelper->getCustomerName($customer));
-        } else {
-            $this->_title->add(__('New Customer'));
-        }
-        /**
-         * Set active menu item
-         */
-        $this->_setActiveMenu('Magento_Customer::customer');
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new customer action
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Delete customer action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $this->_initCustomer();
-        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
-        if (!empty($customerId)) {
-            try {
-                $this->_customerAccountService->deleteCustomer($customerId);
-                $this->messageManager->addSuccess(__('You deleted the customer.'));
-            } catch (\Exception $exception) {
-                $this->messageManager->addError($exception->getMessage());
-            }
-        }
-        $this->_redirect('customer/index');
-    }
-
-    /**
-     * Save customer action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function saveAction()
-    {
-        $returnToEdit = false;
-        $customerId = (int)$this->getRequest()->getPost('customer_id');
-        $originalRequestData = $this->getRequest()->getPost();
-        if ($originalRequestData) {
-            try {
-                // optional fields might be set in request for future processing by observers in other modules
-                $customerData = $this->_extractCustomerData();
-                $addressesData = $this->_extractCustomerAddressData();
-                $request = $this->getRequest();
-                $isExistingCustomer = (bool)$customerId;
-                $customerBuilder = $this->_customerBuilder;
-                if ($isExistingCustomer) {
-                    $savedCustomerData = $this->_customerAccountService->getCustomer($customerId);
-                    $customerData = array_merge(
-                        \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($savedCustomerData),
-                        $customerData
-                    );
-                }
-                unset($customerData[Customer::DEFAULT_BILLING]);
-                unset($customerData[Customer::DEFAULT_SHIPPING]);
-                $customerBuilder->populateWithArray($customerData);
-                $addresses = array();
-                foreach ($addressesData as $addressData) {
-                    $addresses[] = $this->_addressBuilder->populateWithArray($addressData)->create();
-                }
-
-                $this->_eventManager->dispatch(
-                    'adminhtml_customer_prepare_save',
-                    array('customer' => $customerBuilder, 'request' => $request)
-                );
-                $customer = $customerBuilder->create();
-
-                // Save customer
-                $customerDetails = $this->_customerDetailsBuilder->setCustomer(
-                    $customer
-                )->setAddresses($addresses)->create();
-                if ($isExistingCustomer) {
-                    $this->_customerAccountService->updateCustomer($customerDetails);
-                } else {
-                    $customer = $this->_customerAccountService->createCustomer($customerDetails);
-                    $customerId = $customer->getId();
-                }
-
-                $isSubscribed = false;
-                if ($this->_authorization->isAllowed(null)) {
-                    $isSubscribed = $this->getRequest()->getPost('subscription') !== null;
-                }
-                if ($isSubscribed) {
-                    $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
-                } else {
-                    $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
-                }
-
-                // After save
-                $this->_eventManager->dispatch(
-                    'adminhtml_customer_save_after',
-                    array('customer' => $customer, 'request' => $request)
-                );
-                $this->_getSession()->unsCustomerData();
-                // Done Saving customer, finish save action
-                $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId);
-                $this->messageManager->addSuccess(__('You saved the customer.'));
-                $returnToEdit = (bool)$this->getRequest()->getParam('back', false);
-            } catch (\Magento\Framework\Validator\ValidatorException $exception) {
-                $this->_addSessionErrorMessages($exception->getMessages());
-                $this->_getSession()->setCustomerData($originalRequestData);
-                $returnToEdit = true;
-            } catch (\Magento\Framework\Model\Exception $exception) {
-                $messages = $exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR);
-                if (!count($messages)) {
-                    $messages = $exception->getMessage();
-                }
-                $this->_addSessionErrorMessages($messages);
-                $this->_getSession()->setCustomerData($originalRequestData);
-                $returnToEdit = true;
-            } catch (LocalizedException $exception) {
-                $this->_addSessionErrorMessages($exception->getMessage());
-                $this->_getSession()->setCustomerData($originalRequestData);
-                $returnToEdit = true;
-            } catch (\Exception $exception) {
-                $this->messageManager->addException($exception, __('An error occurred while saving the customer.'));
-                $this->_getSession()->setCustomerData($originalRequestData);
-                $returnToEdit = true;
-            }
-        }
-        if ($returnToEdit) {
-            if ($customerId) {
-                $this->_redirect('customer/*/edit', array('id' => $customerId, '_current' => true));
-            } else {
-                $this->_redirect('customer/*/new', array('_current' => true));
-            }
-        } else {
-            $this->_redirect('customer/index');
-        }
-    }
-
-    /**
-     * Reset password handler
-     *
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function resetPasswordAction()
-    {
-        $customerId = (int)$this->getRequest()->getParam('customer_id', 0);
-        if (!$customerId) {
-            return $this->_redirect('customer/index');
-        }
-
-        try {
-            $customer = $this->_customerAccountService->getCustomer($customerId);
-            $this->_customerAccountService->initiatePasswordReset(
-                $customer->getEmail(),
-                CustomerAccountServiceInterface::EMAIL_REMINDER,
-                $customer->getWebsiteId()
-            );
-            $this->messageManager->addSuccess(__('Customer will receive an email with a link to reset password.'));
-        } catch (NoSuchEntityException $exception) {
-            return $this->_redirect('customer/index');
-        } catch (\Magento\Framework\Model\Exception $exception) {
-            $messages = $exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR);
-            if (!count($messages)) {
-                $messages = $exception->getMessage();
-            }
-            $this->_addSessionErrorMessages($messages);
-        } catch (\Exception $exception) {
-            $this->messageManager->addException(
-                $exception,
-                __('An error occurred while resetting customer password.')
-            );
-        }
-
-        $this->_redirect('customer/*/edit', array('id' => $customerId, '_current' => true));
-    }
-
     /**
      * Add errors messages to session.
      *
@@ -537,435 +200,6 @@ class Index extends \Magento\Backend\App\Action
         array_walk_recursive($messages, $callback);
     }
 
-    /**
-     * Reformat customer account data to be compatible with customer service interface
-     *
-     * @return array
-     */
-    protected function _extractCustomerData()
-    {
-        $customerData = array();
-        if ($this->getRequest()->getPost('account')) {
-            $serviceAttributes = array(
-                Customer::DEFAULT_BILLING,
-                Customer::DEFAULT_SHIPPING,
-                'confirmation',
-                'sendemail'
-            );
-            /** @var \Magento\Customer\Helper\Data $customerHelper */
-            $customerHelper = $this->_objectManager->get('Magento\Customer\Helper\Data');
-            $customerData = $customerHelper->extractCustomerData(
-                $this->getRequest(),
-                'adminhtml_customer',
-                CustomerMetadata::ENTITY_TYPE_CUSTOMER,
-                $serviceAttributes,
-                'account'
-            );
-        }
-
-        if (isset($customerData['disable_auto_group_change'])) {
-            $customerData['disable_auto_group_change'] = empty($customerData['disable_auto_group_change']) ? '0' : '1';
-        }
-
-        return $customerData;
-    }
-
-    /**
-     * Reformat customer addresses data to be compatible with customer service interface
-     *
-     * @return array
-     */
-    protected function _extractCustomerAddressData()
-    {
-        $addresses = $this->getRequest()->getPost('address');
-        $customerData = $this->getRequest()->getPost('account');
-        $result = array();
-        if ($addresses) {
-            if (isset($addresses['_template_'])) {
-                unset($addresses['_template_']);
-            }
-
-            $addressIdList = array_keys($addresses);
-            /** @var \Magento\Customer\Helper\Data $customerHelper */
-            $customerHelper = $this->_objectManager->get('Magento\Customer\Helper\Data');
-            foreach ($addressIdList as $addressId) {
-                $scope = sprintf('address/%s', $addressId);
-                $addressData = $customerHelper->extractCustomerData(
-                    $this->getRequest(),
-                    'adminhtml_customer_address',
-                    CustomerMetadata::ENTITY_TYPE_ADDRESS,
-                    array(),
-                    $scope
-                );
-                if (is_numeric($addressId)) {
-                    $addressData['id'] = $addressId;
-                }
-                // Set default billing and shipping flags to address
-                $addressData[Customer::DEFAULT_BILLING] = isset(
-                    $customerData[Customer::DEFAULT_BILLING]
-                    ) &&
-                    $customerData[Customer::DEFAULT_BILLING] &&
-                    $customerData[Customer::DEFAULT_BILLING] == $addressId;
-                $addressData[Customer::DEFAULT_SHIPPING] = isset(
-                    $customerData[Customer::DEFAULT_SHIPPING]
-                    ) &&
-                    $customerData[Customer::DEFAULT_SHIPPING] &&
-                    $customerData[Customer::DEFAULT_SHIPPING] == $addressId;
-
-                $result[] = $addressData;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Customer orders grid
-     *
-     * @return void
-     */
-    public function ordersAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer last orders grid for ajax
-     *
-     * @return void
-     */
-    public function lastOrdersAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer newsletter grid
-     *
-     * @return void
-     */
-    public function newsletterAction()
-    {
-        $this->_initCustomer();
-        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
-        /** @var  \Magento\Newsletter\Model\Subscriber $subscriber */
-        $subscriber = $this->_objectManager
-            ->create('Magento\Newsletter\Model\Subscriber')
-            ->loadByCustomerId($customerId);
-
-        $this->_coreRegistry->register('subscriber', $subscriber);
-        $this->_view->loadLayout()->renderLayout();
-    }
-
-    /**
-     * Wishlist Action
-     *
-     * @return void
-     */
-    public function wishlistAction()
-    {
-        $this->_initCustomer();
-        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
-        $itemId = (int)$this->getRequest()->getParam('delete');
-        if ($customerId && $itemId) {
-            try {
-                $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId)->delete();
-            } catch (\Exception $exception) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($exception);
-            }
-        }
-
-        $this->_view->getLayout()->getUpdate()->addHandle(strtolower($this->_request->getFullActionName()));
-        $this->_view->loadLayoutUpdates();
-        $this->_view->generateLayoutXml();
-        $this->_view->generateLayoutBlocks();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer last view wishlist for ajax
-     *
-     * @return void
-     */
-    public function viewWishlistAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Handle and then get cart grid contents
-     *
-     * @return void
-     */
-    public function cartAction()
-    {
-        $this->_initCustomer();
-        $websiteId = $this->getRequest()->getParam('website_id');
-
-        // delete an item from cart
-        $deleteItemId = $this->getRequest()->getPost('delete');
-        if ($deleteItemId) {
-            $quote = $this->_objectManager->create(
-                'Magento\Sales\Model\Quote'
-            )->setWebsite(
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getWebsite($websiteId)
-            )->loadByCustomer(
-                $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
-            );
-            $item = $quote->getItemById($deleteItemId);
-            if ($item && $item->getId()) {
-                $quote->removeItem($deleteItemId);
-                $quote->collectTotals()->save();
-            }
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('admin.customer.view.edit.cart')->setWebsiteId($websiteId);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get shopping cart to view only
-     *
-     * @return void
-     */
-    public function viewCartAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('admin.customer.view.cart')->setWebsiteId(
-            (int)$this->getRequest()->getParam('website_id')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get shopping carts from all websites for specified client
-     *
-     * @return void
-     */
-    public function cartsAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get customer's product reviews list
-     *
-     * @return void
-     */
-    public function productReviewsAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('admin.customer.reviews')->setCustomerId(
-            $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
-        )
-            ->setUseAjax(true);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * AJAX customer validation action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(0);
-
-        $customer = $this->_validateCustomer($response);
-        if ($customer) {
-            $this->_validateCustomerAddress($response);
-        }
-
-        if ($response->getError()) {
-            $this->_view->getLayout()->initMessages();
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Customer validation
-     *
-     * @param \Magento\Framework\Object $response
-     * @return Customer|null
-     */
-    protected function _validateCustomer($response)
-    {
-        $customer = null;
-        $errors = null;
-
-        try {
-            /** @var Customer $customer */
-            $customer = $this->_customerBuilder->create();
-
-            $customerForm = $this->_formFactory->create(
-                'customer',
-                'adminhtml_customer',
-                \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($customer),
-                true
-            );
-            $customerForm->setInvisibleIgnored(true);
-
-            $data = $customerForm->extractData($this->getRequest(), 'account');
-
-            if ($customer->getWebsiteId()) {
-                unset($data['website_id']);
-            }
-
-            $customer = $this->_customerBuilder->populateWithArray($data)->create();
-            $errors = $this->_customerAccountService->validateCustomerData($customer);
-        } catch (\Magento\Framework\Model\Exception $exception) {
-            /* @var $error Error */
-            foreach ($exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR) as $error) {
-                $errors[] = $error->getText();
-            }
-        }
-
-        if (!$errors->isValid()) {
-            foreach ($errors->getMessages() as $error) {
-                $this->messageManager->addError($error);
-            }
-            $response->setError(1);
-        }
-
-        return $customer;
-    }
-
-    /**
-     * Customer address validation.
-     *
-     * @param \Magento\Framework\Object $response
-     * @return void
-     */
-    protected function _validateCustomerAddress($response)
-    {
-        $addressesData = $this->getRequest()->getParam('address');
-        if (is_array($addressesData)) {
-            foreach (array_keys($addressesData) as $index) {
-                if ($index == '_template_') {
-                    continue;
-                }
-
-                $addressForm = $this->_formFactory->create('customer_address', 'adminhtml_customer_address');
-
-                $requestScope = sprintf('address/%s', $index);
-                $formData = $addressForm->extractData($this->getRequest(), $requestScope);
-
-                $errors = $addressForm->validateData($formData);
-                if ($errors !== true) {
-                    foreach ($errors as $error) {
-                        $this->messageManager->addError($error);
-                    }
-                    $response->setError(1);
-                }
-            }
-        }
-    }
-
-    /**
-     * Customer mass subscribe action
-     *
-     * @return void
-     */
-    public function massSubscribeAction()
-    {
-        $customerIds = $this->getRequest()->getParam('customer');
-        $customersUpdated = $this->actUponMultipleCustomers(
-            function ($customerId) {
-                // Verify customer exists
-                $this->_customerAccountService->getCustomer($customerId);
-                $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
-            },
-            $customerIds
-        );
-        if ($customersUpdated) {
-            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
-        }
-        $this->_redirect('customer/*/index');
-    }
-
-    /**
-     * Customer mass unsubscribe action
-     *
-     * @return void
-     */
-    public function massUnsubscribeAction()
-    {
-        $customerIds = $this->getRequest()->getParam('customer');
-        $customersUpdated = $this->actUponMultipleCustomers(
-            function ($customerId) {
-                // Verify customer exists
-                $this->_customerAccountService->getCustomer($customerId);
-                $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
-            },
-            $customerIds
-        );
-        if ($customersUpdated) {
-            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
-        }
-        $this->_redirect('customer/*/index');
-    }
-
-    /**
-     * Customer mass delete action
-     *
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $customerIds = $this->getRequest()->getParam('customer');
-        $customersDeleted = $this->actUponMultipleCustomers(
-            function ($customerId) {
-                $this->_customerAccountService->deleteCustomer($customerId);
-            },
-            $customerIds
-        );
-        if ($customersDeleted) {
-            $this->messageManager->addSuccess(__('A total of %1 record(s) were deleted.', $customersDeleted));
-        }
-        $this->_redirect('customer/*/index');
-    }
-
-    /**
-     * Customer mass assign group action
-     *
-     * @return void
-     */
-    public function massAssignGroupAction()
-    {
-        $customerIds = $this->getRequest()->getParam('customer');
-        $customersUpdated = $this->actUponMultipleCustomers(
-            function ($customerId) {
-                // Verify customer exists
-                $customer = $this->_customerAccountService->getCustomer($customerId);
-                $this->_customerBuilder->populate($customer);
-                $customer = $this->_customerBuilder->setGroupId($this->getRequest()->getParam('group'))->create();
-                $customerDetails = $this->_customerDetailsBuilder
-                    ->setCustomer($customer)
-                    ->create();
-                $this->_customerAccountService->updateCustomer($customerDetails);
-            },
-            $customerIds
-        );
-        if ($customersUpdated) {
-            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
-        }
-        $this->_redirect('customer/*/index');
-    }
-
     /**
      * Helper function that handles mass actions by taking in a callable for handling a single customer action.
      *
@@ -991,92 +225,6 @@ class Index extends \Magento\Backend\App\Action
         return $customersUpdated;
     }
 
-    /**
-     * Customer view file action
-     *
-     * @return void
-     * @throws NotFoundException
-     *
-     * @SuppressWarnings(PHPMD.ExitExpression)
-     */
-    public function viewfileAction()
-    {
-        $file = null;
-        $plain = false;
-        if ($this->getRequest()->getParam('file')) {
-            // download file
-            $file = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->urlDecode(
-                $this->getRequest()->getParam('file')
-            );
-        } elseif ($this->getRequest()->getParam('image')) {
-            // show plain image
-            $file = $this->_objectManager->get('Magento\Core\Helper\Data')->urlDecode(
-                $this->getRequest()->getParam('image')
-            );
-            $plain = true;
-        } else {
-            throw new NotFoundException();
-        }
-
-        /** @var \Magento\Framework\App\Filesystem $filesystem */
-        $filesystem = $this->_objectManager->get('Magento\Framework\App\Filesystem');
-        $directory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MEDIA_DIR);
-        $fileName = 'customer' . '/' . ltrim($file, '/');
-        $path = $directory->getAbsolutePath($fileName);
-        if (!$directory->isFile($fileName)
-            && !$this->_objectManager->get('Magento\Core\Helper\File\Storage')->processStorageFile($path)
-        ) {
-            throw new NotFoundException();
-        }
-
-        if ($plain) {
-            $extension = pathinfo($path, PATHINFO_EXTENSION);
-            switch (strtolower($extension)) {
-                case 'gif':
-                    $contentType = 'image/gif';
-                    break;
-                case 'jpg':
-                    $contentType = 'image/jpeg';
-                    break;
-                case 'png':
-                    $contentType = 'image/png';
-                    break;
-                default:
-                    $contentType = 'application/octet-stream';
-                    break;
-            }
-            $stat = $directory->stat($path);
-            $contentLength = $stat['size'];
-            $contentModify = $stat['mtime'];
-
-            $this->getResponse()
-                ->setHttpResponseCode(200)
-                ->setHeader('Pragma', 'public', true)
-                ->setHeader(
-                    'Content-type',
-                    $contentType,
-                    true
-                )
-                ->setHeader('Content-Length', $contentLength)
-                ->setHeader('Last-Modified', date('r', $contentModify))
-                ->clearBody();
-            $this->getResponse()->sendHeaders();
-
-            echo $directory->readFile($fileName);
-        } else {
-            $name = pathinfo($path, PATHINFO_BASENAME);
-            $this->_fileFactory->create(
-                $name,
-                array('type' => 'filename', 'value' => $fileName),
-                \Magento\Framework\App\Filesystem::MEDIA_DIR
-            )->sendResponse();
-        }
-
-        exit;
-    }
-
     /**
      * Customer access rights checking
      *
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Cart.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Cart.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff43ec8f6acafa812245fcb08cb2be1607d0ce88
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Cart.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class Cart extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Handle and then get cart grid contents
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $websiteId = $this->getRequest()->getParam('website_id');
+
+        // delete an item from cart
+        $deleteItemId = $this->getRequest()->getPost('delete');
+        if ($deleteItemId) {
+            $quote = $this->_objectManager->create(
+                'Magento\Sales\Model\Quote'
+            )->setWebsite(
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getWebsite($websiteId)
+            )->loadByCustomer(
+                $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
+            );
+            $item = $quote->getItemById($deleteItemId);
+            if ($item && $item->getId()) {
+                $quote->removeItem($deleteItemId);
+                $quote->collectTotals()->save();
+            }
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('admin.customer.view.edit.cart')->setWebsiteId($websiteId);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Carts.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Carts.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9f740ecef6ababb38d34f24d64ae84c1d67c2e7
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Carts.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class Carts extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Get shopping carts from all websites for specified client
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..e94e04aede37eb05354c61552f39317dd9131812
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Delete.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class Delete extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Delete customer action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
+        if (!empty($customerId)) {
+            try {
+                $this->_customerAccountService->deleteCustomer($customerId);
+                $this->messageManager->addSuccess(__('You deleted the customer.'));
+            } catch (\Exception $exception) {
+                $this->messageManager->addError($exception->getMessage());
+            }
+        }
+        $this->_redirect('customer/index');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d0bf899a6e5070587b5349a2e0ffcdf4fa23b8a
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Edit.php
@@ -0,0 +1,152 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Service\V1\Data\Customer;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Customer\Service\V1\Data\AddressConverter;
+
+class Edit extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer edit action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function execute()
+    {
+        $customerId = $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Customer::customer_manage');
+
+        $customerData = array();
+        $customerData['account'] = array();
+        $customerData['address'] = array();
+        $customer = null;
+        $isExistingCustomer = (bool)$customerId;
+        if ($isExistingCustomer) {
+            try {
+                $customer = $this->_customerAccountService->getCustomer($customerId);
+                $customerData['account'] = \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($customer);
+                $customerData['account']['id'] = $customerId;
+                try {
+                    $addresses = $this->_addressService->getAddresses($customerId);
+                    foreach ($addresses as $address) {
+                        $customerData['address'][$address->getId()] = AddressConverter::toFlatArray($address);
+                        $customerData['address'][$address->getId()]['id'] = $address->getId();
+                    }
+                } catch (NoSuchEntityException $e) {
+                    //do nothing
+                }
+            } catch (NoSuchEntityException $e) {
+                $this->messageManager->addException($e, __('An error occurred while editing the customer.'));
+                $this->_redirect('customer/*/index');
+                return;
+            }
+        }
+        $customerData['customer_id'] = $customerId;
+
+        // set entered data if was error when we do save
+        $data = $this->_getSession()->getCustomerData(true);
+
+        // restore data from SESSION
+        if ($data && (!isset(
+                $data['customer_id']
+                ) || isset(
+                $data['customer_id']
+                ) && $data['customer_id'] == $customerId)
+        ) {
+            $request = clone $this->getRequest();
+            $request->setParams($data);
+
+            if (isset($data['account']) && is_array($data['account'])) {
+                $customerForm = $this->_formFactory->create(
+                    'customer',
+                    'adminhtml_customer',
+                    $customerData['account'],
+                    true
+                );
+                $formData = $customerForm->extractData($request, 'account');
+                $customerData['account'] = $customerForm->restoreData($formData);
+                $customer = $this->_customerBuilder->populateWithArray($customerData['account'])->create();
+            }
+
+            if (isset($data['address']) && is_array($data['address'])) {
+                foreach (array_keys($data['address']) as $addressId) {
+                    if ($addressId == '_template_') {
+                        continue;
+                    }
+
+                    try {
+                        $address = $this->_addressService->getAddress($addressId);
+                        if (!empty($customerId) && $address->getCustomerId() == $customerId) {
+                            $this->_addressBuilder->populate($address);
+                        }
+                    } catch (NoSuchEntityException $e) {
+                        $this->_addressBuilder->setId($addressId);
+                    }
+                    if (!empty($customerId)) {
+                        $this->_addressBuilder->setCustomerId($customerId);
+                    }
+                    $this->_addressBuilder->setDefaultBilling(
+                        !empty($data['account'][Customer::DEFAULT_BILLING]) &&
+                        $data['account'][Customer::DEFAULT_BILLING] == $addressId
+                    );
+                    $this->_addressBuilder->setDefaultShipping(
+                        !empty($data['account'][Customer::DEFAULT_SHIPPING]) &&
+                        $data['account'][Customer::DEFAULT_SHIPPING] == $addressId
+                    );
+                    $address = $this->_addressBuilder->create();
+                    $requestScope = sprintf('address/%s', $addressId);
+                    $addressForm = $this->_formFactory->create(
+                        'customer_address',
+                        'adminhtml_customer_address',
+                        AddressConverter::toFlatArray($address)
+                    );
+                    $formData = $addressForm->extractData($request, $requestScope);
+                    $customerData['address'][$addressId] = $addressForm->restoreData($formData);
+                    $customerData['address'][$addressId]['id'] = $addressId;
+                }
+            }
+        }
+
+        $this->_getSession()->setCustomerData($customerData);
+
+        if ($isExistingCustomer) {
+            $this->_title->add($this->_viewHelper->getCustomerName($customer));
+        } else {
+            $this->_title->add(__('New Customer'));
+        }
+        /**
+         * Set active menu item
+         */
+        $this->_setActiveMenu('Magento_Customer::customer');
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Grid.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..cdea1bf320cc810ffb382697fb85bccc19e3e16e
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class Grid extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Index.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..97deddec59629e4582ae5635340be3675f20d60a
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Index.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class Index extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customers list action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customers'));
+
+        if ($this->getRequest()->getQuery('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+        $this->_view->loadLayout();
+
+        /**
+         * Set active menu item
+         */
+        $this->_setActiveMenu('Magento_Customer::customer_manage');
+
+        /**
+         * Add breadcrumb item
+         */
+        $this->_addBreadcrumb(__('Customers'), __('Customers'));
+        $this->_addBreadcrumb(__('Manage Customers'), __('Manage Customers'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/LastOrders.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/LastOrders.php
new file mode 100644
index 0000000000000000000000000000000000000000..bdee69973a0bad30d78b55742a37381799d4e991
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/LastOrders.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class LastOrders extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer last orders grid for ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php
new file mode 100644
index 0000000000000000000000000000000000000000..c143d64cdd6579e2f981840446c2a32027865431
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassAssignGroup.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class MassAssignGroup extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer mass assign group action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customerIds = $this->getRequest()->getParam('customer');
+        $customersUpdated = $this->actUponMultipleCustomers(
+            function ($customerId) {
+                // Verify customer exists
+                $customer = $this->_customerAccountService->getCustomer($customerId);
+                $this->_customerBuilder->populate($customer);
+                $customer = $this->_customerBuilder->setGroupId($this->getRequest()->getParam('group'))->create();
+                $customerDetails = $this->_customerDetailsBuilder
+                    ->setCustomer($customer)
+                    ->create();
+                $this->_customerAccountService->updateCustomer($customerDetails);
+            },
+            $customerIds
+        );
+        if ($customersUpdated) {
+            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
+        }
+        $this->_redirect('customer/*/index');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1c838eca294db41dcf8f8cdf4b96bb8166cff58
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassDelete.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class MassDelete extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer mass delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customerIds = $this->getRequest()->getParam('customer');
+        $customersDeleted = $this->actUponMultipleCustomers(
+            function ($customerId) {
+                $this->_customerAccountService->deleteCustomer($customerId);
+            },
+            $customerIds
+        );
+        if ($customersDeleted) {
+            $this->messageManager->addSuccess(__('A total of %1 record(s) were deleted.', $customersDeleted));
+        }
+        $this->_redirect('customer/*/index');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf1dbdac9f69152b50c7acf47985fc3405bbebdc
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassSubscribe.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class MassSubscribe extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer mass subscribe action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customerIds = $this->getRequest()->getParam('customer');
+        $customersUpdated = $this->actUponMultipleCustomers(
+            function ($customerId) {
+                // Verify customer exists
+                $this->_customerAccountService->getCustomer($customerId);
+                $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
+            },
+            $customerIds
+        );
+        if ($customersUpdated) {
+            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
+        }
+        $this->_redirect('customer/*/index');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b195c8dbabef510ccf543b138f60301fd11309f
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/MassUnsubscribe.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class MassUnsubscribe extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer mass unsubscribe action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customerIds = $this->getRequest()->getParam('customer');
+        $customersUpdated = $this->actUponMultipleCustomers(
+            function ($customerId) {
+                // Verify customer exists
+                $this->_customerAccountService->getCustomer($customerId);
+                $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
+            },
+            $customerIds
+        );
+        if ($customersUpdated) {
+            $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', $customersUpdated));
+        }
+        $this->_redirect('customer/*/index');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/NewAction.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd17dda1230a843f7cf3391df041d7490db91499
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class NewAction extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Create new customer action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Newsletter.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Newsletter.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba89d4969a14145f0f6d92b68525ec00858c8949
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Newsletter.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class Newsletter extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer newsletter grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
+        /** @var  \Magento\Newsletter\Model\Subscriber $subscriber */
+        $subscriber = $this->_objectManager
+            ->create('Magento\Newsletter\Model\Subscriber')
+            ->loadByCustomerId($customerId);
+
+        $this->_coreRegistry->register('subscriber', $subscriber);
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Orders.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Orders.php
new file mode 100644
index 0000000000000000000000000000000000000000..f753674cd3cdab8638556fc2e8db4346e6746a05
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Orders.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class Orders extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer orders grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ProductReviews.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ProductReviews.php
new file mode 100644
index 0000000000000000000000000000000000000000..fed638ec1c6e6859108f87ff7f2538fa2e6d6858
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ProductReviews.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class ProductReviews extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Get customer's product reviews list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('admin.customer.reviews')->setCustomerId(
+            $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
+        )
+            ->setUseAjax(true);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..527e65769f21276907e5432b35b6e5b4f650de12
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ResetPassword.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class ResetPassword extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Reset password handler
+     *
+     * @return \Magento\Framework\App\ResponseInterface
+     */
+    public function execute()
+    {
+        $customerId = (int)$this->getRequest()->getParam('customer_id', 0);
+        if (!$customerId) {
+            return $this->_redirect('customer/index');
+        }
+
+        try {
+            $customer = $this->_customerAccountService->getCustomer($customerId);
+            $this->_customerAccountService->initiatePasswordReset(
+                $customer->getEmail(),
+                CustomerAccountServiceInterface::EMAIL_REMINDER,
+                $customer->getWebsiteId()
+            );
+            $this->messageManager->addSuccess(__('Customer will receive an email with a link to reset password.'));
+        } catch (NoSuchEntityException $exception) {
+            return $this->_redirect('customer/index');
+        } catch (\Magento\Framework\Model\Exception $exception) {
+            $messages = $exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR);
+            if (!count($messages)) {
+                $messages = $exception->getMessage();
+            }
+            $this->_addSessionErrorMessages($messages);
+        } catch (\Exception $exception) {
+            $this->messageManager->addException(
+                $exception,
+                __('An error occurred while resetting customer password.')
+            );
+        }
+
+        $this->_redirect('customer/*/edit', array('id' => $customerId, '_current' => true));
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..0795505f15d8c38ac92a47fc8008f46b6c0ffb33
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+use Magento\Customer\Service\V1\Data\Customer;
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Customer\Service\V1\CustomerMetadataServiceInterface as CustomerMetadata;
+
+class Save extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Reformat customer account data to be compatible with customer service interface
+     *
+     * @return array
+     */
+    protected function _extractCustomerData()
+    {
+        $customerData = array();
+        if ($this->getRequest()->getPost('account')) {
+            $serviceAttributes = array(
+                Customer::DEFAULT_BILLING,
+                Customer::DEFAULT_SHIPPING,
+                'confirmation',
+                'sendemail'
+            );
+            /** @var \Magento\Customer\Helper\Data $customerHelper */
+            $customerHelper = $this->_objectManager->get('Magento\Customer\Helper\Data');
+            $customerData = $customerHelper->extractCustomerData(
+                $this->getRequest(),
+                'adminhtml_customer',
+                CustomerMetadata::ENTITY_TYPE_CUSTOMER,
+                $serviceAttributes,
+                'account'
+            );
+        }
+
+        if (isset($customerData['disable_auto_group_change'])) {
+            $customerData['disable_auto_group_change'] = empty($customerData['disable_auto_group_change']) ? '0' : '1';
+        }
+
+        return $customerData;
+    }
+
+    /**
+     * Reformat customer addresses data to be compatible with customer service interface
+     *
+     * @return array
+     */
+    protected function _extractCustomerAddressData()
+    {
+        $addresses = $this->getRequest()->getPost('address');
+        $customerData = $this->getRequest()->getPost('account');
+        $result = array();
+        if ($addresses) {
+            if (isset($addresses['_template_'])) {
+                unset($addresses['_template_']);
+            }
+
+            $addressIdList = array_keys($addresses);
+            /** @var \Magento\Customer\Helper\Data $customerHelper */
+            $customerHelper = $this->_objectManager->get('Magento\Customer\Helper\Data');
+            foreach ($addressIdList as $addressId) {
+                $scope = sprintf('address/%s', $addressId);
+                $addressData = $customerHelper->extractCustomerData(
+                    $this->getRequest(),
+                    'adminhtml_customer_address',
+                    CustomerMetadata::ENTITY_TYPE_ADDRESS,
+                    array(),
+                    $scope
+                );
+                if (is_numeric($addressId)) {
+                    $addressData['id'] = $addressId;
+                }
+                // Set default billing and shipping flags to address
+                $addressData[Customer::DEFAULT_BILLING] = isset(
+                    $customerData[Customer::DEFAULT_BILLING]
+                    ) &&
+                    $customerData[Customer::DEFAULT_BILLING] &&
+                    $customerData[Customer::DEFAULT_BILLING] == $addressId;
+                $addressData[Customer::DEFAULT_SHIPPING] = isset(
+                    $customerData[Customer::DEFAULT_SHIPPING]
+                    ) &&
+                    $customerData[Customer::DEFAULT_SHIPPING] &&
+                    $customerData[Customer::DEFAULT_SHIPPING] == $addressId;
+
+                $result[] = $addressData;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Save customer action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        $returnToEdit = false;
+        $customerId = (int)$this->getRequest()->getPost('customer_id');
+        $originalRequestData = $this->getRequest()->getPost();
+        if ($originalRequestData) {
+            try {
+                // optional fields might be set in request for future processing by observers in other modules
+                $customerData = $this->_extractCustomerData();
+                $addressesData = $this->_extractCustomerAddressData();
+                $request = $this->getRequest();
+                $isExistingCustomer = (bool)$customerId;
+                $customerBuilder = $this->_customerBuilder;
+                if ($isExistingCustomer) {
+                    $savedCustomerData = $this->_customerAccountService->getCustomer($customerId);
+                    $customerData = array_merge(
+                        \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($savedCustomerData),
+                        $customerData
+                    );
+                }
+                unset($customerData[Customer::DEFAULT_BILLING]);
+                unset($customerData[Customer::DEFAULT_SHIPPING]);
+                $customerBuilder->populateWithArray($customerData);
+                $addresses = array();
+                foreach ($addressesData as $addressData) {
+                    $addresses[] = $this->_addressBuilder->populateWithArray($addressData)->create();
+                }
+
+                $this->_eventManager->dispatch(
+                    'adminhtml_customer_prepare_save',
+                    array('customer' => $customerBuilder, 'request' => $request)
+                );
+                $customer = $customerBuilder->create();
+
+                // Save customer
+                $customerDetails = $this->_customerDetailsBuilder->setCustomer(
+                    $customer
+                )->setAddresses($addresses)->create();
+                if ($isExistingCustomer) {
+                    $this->_customerAccountService->updateCustomer($customerDetails);
+                } else {
+                    $customer = $this->_customerAccountService->createCustomer($customerDetails);
+                    $customerId = $customer->getId();
+                }
+
+                $isSubscribed = false;
+                if ($this->_authorization->isAllowed(null)) {
+                    $isSubscribed = $this->getRequest()->getPost('subscription') !== null;
+                }
+                if ($isSubscribed) {
+                    $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
+                } else {
+                    $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
+                }
+
+                // After save
+                $this->_eventManager->dispatch(
+                    'adminhtml_customer_save_after',
+                    array('customer' => $customer, 'request' => $request)
+                );
+                $this->_getSession()->unsCustomerData();
+                // Done Saving customer, finish save action
+                $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId);
+                $this->messageManager->addSuccess(__('You saved the customer.'));
+                $returnToEdit = (bool)$this->getRequest()->getParam('back', false);
+            } catch (\Magento\Framework\Validator\ValidatorException $exception) {
+                $this->_addSessionErrorMessages($exception->getMessages());
+                $this->_getSession()->setCustomerData($originalRequestData);
+                $returnToEdit = true;
+            } catch (\Magento\Framework\Model\Exception $exception) {
+                $messages = $exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR);
+                if (!count($messages)) {
+                    $messages = $exception->getMessage();
+                }
+                $this->_addSessionErrorMessages($messages);
+                $this->_getSession()->setCustomerData($originalRequestData);
+                $returnToEdit = true;
+            } catch (LocalizedException $exception) {
+                $this->_addSessionErrorMessages($exception->getMessage());
+                $this->_getSession()->setCustomerData($originalRequestData);
+                $returnToEdit = true;
+            } catch (\Exception $exception) {
+                $this->messageManager->addException($exception, __('An error occurred while saving the customer.'));
+                $this->_getSession()->setCustomerData($originalRequestData);
+                $returnToEdit = true;
+            }
+        }
+        if ($returnToEdit) {
+            if ($customerId) {
+                $this->_redirect('customer/*/edit', array('id' => $customerId, '_current' => true));
+            } else {
+                $this->_redirect('customer/*/new', array('_current' => true));
+            }
+        } else {
+            $this->_redirect('customer/index');
+        }
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..e64fe0bd7c68790fac217a6594267af6d5516411
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Validate.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use \Magento\Customer\Service\V1\Data\Customer;
+use Magento\Framework\Message\Error;
+
+class Validate extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer validation
+     *
+     * @param \Magento\Framework\Object $response
+     * @return Customer|null
+     */
+    protected function _validateCustomer($response)
+    {
+        $customer = null;
+        $errors = null;
+
+        try {
+            /** @var Customer $customer */
+            $customer = $this->_customerBuilder->create();
+
+            $customerForm = $this->_formFactory->create(
+                'customer',
+                'adminhtml_customer',
+                \Magento\Framework\Service\EavDataObjectConverter::toFlatArray($customer),
+                true
+            );
+            $customerForm->setInvisibleIgnored(true);
+
+            $data = $customerForm->extractData($this->getRequest(), 'account');
+
+            if ($customer->getWebsiteId()) {
+                unset($data['website_id']);
+            }
+
+            $customer = $this->_customerBuilder->populateWithArray($data)->create();
+            $errors = $this->_customerAccountService->validateCustomerData($customer);
+        } catch (\Magento\Framework\Model\Exception $exception) {
+            /* @var $error Error */
+            foreach ($exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR) as $error) {
+                $errors[] = $error->getText();
+            }
+        }
+
+        if (!$errors->isValid()) {
+            foreach ($errors->getMessages() as $error) {
+                $this->messageManager->addError($error);
+            }
+            $response->setError(1);
+        }
+
+        return $customer;
+    }
+
+    /**
+     * Customer address validation.
+     *
+     * @param \Magento\Framework\Object $response
+     * @return void
+     */
+    protected function _validateCustomerAddress($response)
+    {
+        $addressesData = $this->getRequest()->getParam('address');
+        if (is_array($addressesData)) {
+            foreach (array_keys($addressesData) as $index) {
+                if ($index == '_template_') {
+                    continue;
+                }
+
+                $addressForm = $this->_formFactory->create('customer_address', 'adminhtml_customer_address');
+
+                $requestScope = sprintf('address/%s', $index);
+                $formData = $addressForm->extractData($this->getRequest(), $requestScope);
+
+                $errors = $addressForm->validateData($formData);
+                if ($errors !== true) {
+                    foreach ($errors as $error) {
+                        $this->messageManager->addError($error);
+                    }
+                    $response->setError(1);
+                }
+            }
+        }
+    }
+
+    /**
+     * AJAX customer validation action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(0);
+
+        $customer = $this->_validateCustomer($response);
+        if ($customer) {
+            $this->_validateCustomerAddress($response);
+        }
+
+        if ($response->getError()) {
+            $this->_view->getLayout()->initMessages();
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewCart.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewCart.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a60a1b582ac24d90e2216bb2a8a8239314e7fbd
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewCart.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class ViewCart extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Get shopping cart to view only
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('admin.customer.view.cart')->setWebsiteId(
+            (int)$this->getRequest()->getParam('website_id')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewWishlist.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewWishlist.php
new file mode 100644
index 0000000000000000000000000000000000000000..17ffa042ac08c2eb77d78a87c62e970bcf274bc6
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/ViewWishlist.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+class ViewWishlist extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer last view wishlist for ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Viewfile.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Viewfile.php
new file mode 100644
index 0000000000000000000000000000000000000000..77e16668710be3c516f65c16bc2b828f7200074a
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Viewfile.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Framework\App\Action\NotFoundException;
+
+class Viewfile extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Customer view file action
+     *
+     * @return void
+     * @throws NotFoundException
+     *
+     * @SuppressWarnings(PHPMD.ExitExpression)
+     */
+    public function execute()
+    {
+        $file = null;
+        $plain = false;
+        if ($this->getRequest()->getParam('file')) {
+            // download file
+            $file = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->urlDecode(
+                $this->getRequest()->getParam('file')
+            );
+        } elseif ($this->getRequest()->getParam('image')) {
+            // show plain image
+            $file = $this->_objectManager->get('Magento\Core\Helper\Data')->urlDecode(
+                $this->getRequest()->getParam('image')
+            );
+            $plain = true;
+        } else {
+            throw new NotFoundException();
+        }
+
+        /** @var \Magento\Framework\App\Filesystem $filesystem */
+        $filesystem = $this->_objectManager->get('Magento\Framework\App\Filesystem');
+        $directory = $filesystem->getDirectoryRead(\Magento\Framework\App\Filesystem::MEDIA_DIR);
+        $fileName = 'customer' . '/' . ltrim($file, '/');
+        $path = $directory->getAbsolutePath($fileName);
+        if (!$directory->isFile($fileName)
+            && !$this->_objectManager->get('Magento\Core\Helper\File\Storage')->processStorageFile($path)
+        ) {
+            throw new NotFoundException();
+        }
+
+        if ($plain) {
+            $extension = pathinfo($path, PATHINFO_EXTENSION);
+            switch (strtolower($extension)) {
+                case 'gif':
+                    $contentType = 'image/gif';
+                    break;
+                case 'jpg':
+                    $contentType = 'image/jpeg';
+                    break;
+                case 'png':
+                    $contentType = 'image/png';
+                    break;
+                default:
+                    $contentType = 'application/octet-stream';
+                    break;
+            }
+            $stat = $directory->stat($path);
+            $contentLength = $stat['size'];
+            $contentModify = $stat['mtime'];
+
+            $this->getResponse()
+                ->setHttpResponseCode(200)
+                ->setHeader('Pragma', 'public', true)
+                ->setHeader(
+                    'Content-type',
+                    $contentType,
+                    true
+                )
+                ->setHeader('Content-Length', $contentLength)
+                ->setHeader('Last-Modified', date('r', $contentModify))
+                ->clearBody();
+            $this->getResponse()->sendHeaders();
+
+            echo $directory->readFile($fileName);
+        } else {
+            $name = pathinfo($path, PATHINFO_BASENAME);
+            $this->_fileFactory->create(
+                $name,
+                array('type' => 'filename', 'value' => $fileName),
+                \Magento\Framework\App\Filesystem::MEDIA_DIR
+            )->sendResponse();
+        }
+
+        exit;
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc49d35318a2d666c91468dca615057a11db54e4
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Index/Wishlist.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+use Magento\Customer\Controller\RegistryConstants;
+
+class Wishlist extends \Magento\Customer\Controller\Adminhtml\Index
+{
+    /**
+     * Wishlist Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initCustomer();
+        $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
+        $itemId = (int)$this->getRequest()->getParam('delete');
+        if ($customerId && $itemId) {
+            try {
+                $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId)->delete();
+            } catch (\Exception $exception) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($exception);
+            }
+        }
+
+        $this->_view->getLayout()->getUpdate()->addHandle(strtolower($this->_request->getFullActionName()));
+        $this->_view->loadLayoutUpdates();
+        $this->_view->generateLayoutXml();
+        $this->_view->generateLayoutBlocks();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Online.php b/app/code/Magento/Customer/Controller/Adminhtml/Online/Index.php
similarity index 92%
rename from app/code/Magento/Customer/Controller/Adminhtml/Online.php
rename to app/code/Magento/Customer/Controller/Adminhtml/Online/Index.php
index ed5777794d97ae4bb8f5944e7222b10cb24c46a6..dab423fbba51c2bc259b85407036d35da3c532bb 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Online.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Online/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Customer\Controller\Adminhtml;
+namespace Magento\Customer\Controller\Adminhtml\Online;
 
-class Online extends \Magento\Backend\App\Action
+class Index extends \Magento\Backend\App\Action
 {
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Customer::online');
+    }
+
     /**
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->_title->add(__('Customers Now Online'));
 
@@ -46,12 +55,4 @@ class Online extends \Magento\Backend\App\Action
 
         $this->_view->renderLayout();
     }
-
-    /**
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Customer::online');
-    }
 }
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php
index 0c45c2ec434c0e6424b6ff76e06c5cc02b16913a..c88d6df4e401e8cfc6ed0d646916eb6f44ebbad8 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat.php
@@ -44,47 +44,4 @@ class Validatevat extends \Magento\Backend\App\Action
             $this->getRequest()->getParam('vat')
         );
     }
-
-    /**
-     * Check whether vat is valid
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $result = $this->_validate();
-        $this->getResponse()->setBody((int)$result->getIsValid());
-    }
-
-    /**
-     * Retrieve validation result as JSON
-     *
-     * @return void
-     */
-    public function validateAdvancedAction()
-    {
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-
-        $result = $this->_validate();
-        $valid = $result->getIsValid();
-        $success = $result->getRequestSuccess();
-        // ID of the store where order is placed
-        $storeId = $this->getRequest()->getParam('store_id');
-        // Sanitize value if needed
-        if (!is_null($storeId)) {
-            $storeId = (int)$storeId;
-        }
-
-        $groupId = $this->_objectManager->get(
-            'Magento\Customer\Helper\Data'
-        )->getCustomerGroupIdBasedOnVatNumber(
-            $this->getRequest()->getParam('country'),
-            $result,
-            $storeId
-        );
-
-        $body = $coreHelper->jsonEncode(array('valid' => $valid, 'group' => $groupId, 'success' => $success));
-        $this->getResponse()->representJson($body);
-    }
 }
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..392a907bede6109c6c1873d672a680d903b60490
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/Validate.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\System\Config\Validatevat;
+
+class Validate extends \Magento\Customer\Controller\Adminhtml\System\Config\Validatevat
+{
+    /**
+     * Check whether vat is valid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $result = $this->_validate();
+        $this->getResponse()->setBody((int)$result->getIsValid());
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/ValidateAdvanced.php b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/ValidateAdvanced.php
new file mode 100644
index 0000000000000000000000000000000000000000..85488191350a769e2a1964e02417634cbae897be
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/System/Config/Validatevat/ValidateAdvanced.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\System\Config\Validatevat;
+
+class ValidateAdvanced extends \Magento\Customer\Controller\Adminhtml\System\Config\Validatevat
+{
+    /**
+     * Retrieve validation result as JSON
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+
+        $result = $this->_validate();
+        $valid = $result->getIsValid();
+        $success = $result->getRequestSuccess();
+        // ID of the store where order is placed
+        $storeId = $this->getRequest()->getParam('store_id');
+        // Sanitize value if needed
+        if (!is_null($storeId)) {
+            $storeId = (int)$storeId;
+        }
+
+        $groupId = $this->_objectManager->get(
+            'Magento\Customer\Helper\Data'
+        )->getCustomerGroupIdBasedOnVatNumber(
+            $this->getRequest()->getParam('country'),
+            $result,
+            $storeId
+        );
+
+        $body = $coreHelper->jsonEncode(array('valid' => $valid, 'group' => $groupId, 'success' => $success));
+        $this->getResponse()->representJson($body);
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist.php b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist.php
index 8f58df2f8d1956e0340be8234bf8c231031a19ce..42a22cc05a92847c5a106b3a1eba5d16e0d71537 100644
--- a/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist.php
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist.php
@@ -23,7 +23,6 @@
  */
 namespace Magento\Customer\Controller\Adminhtml\Wishlist\Product\Composite;
 
-use Exception;
 use Magento\Framework\Model\Exception as CoreException;
 
 /**
@@ -76,63 +75,6 @@ class Wishlist extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Ajax handler to response configuration fieldset of composite product in customer's wishlist.
-     *
-     * @return void
-     */
-    public function configureAction()
-    {
-        $configureResult = new \Magento\Framework\Object();
-        try {
-            $this->_initData();
-
-            $configureResult->setProductId($this->_wishlistItem->getProductId());
-            $configureResult->setBuyRequest($this->_wishlistItem->getBuyRequest());
-            $configureResult->setCurrentStoreId($this->_wishlistItem->getStoreId());
-            $configureResult->setCurrentCustomerId($this->_wishlist->getCustomerId());
-
-            $configureResult->setOk(true);
-        } catch (Exception $e) {
-            $configureResult->setError(true);
-            $configureResult->setMessage($e->getMessage());
-        }
-
-        $this->_objectManager->get(
-            'Magento\Catalog\Helper\Product\Composite'
-        )->renderConfigureResult(
-            $configureResult
-        );
-    }
-
-    /**
-     * IFrame handler for submitted configuration for wishlist item.
-     *
-     * @return false
-     */
-    public function updateAction()
-    {
-        // Update wishlist item
-        $updateResult = new \Magento\Framework\Object();
-        try {
-            $this->_initData();
-
-            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
-
-            $this->_wishlist->updateItem($this->_wishlistItem->getId(), $buyRequest)->save();
-
-            $updateResult->setOk(true);
-        } catch (Exception $e) {
-            $updateResult->setError(true);
-            $updateResult->setMessage($e->getMessage());
-        }
-        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
-        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
-        $this->_redirect('catalog/product/showUpdateResult');
-
-        return false;
-    }
-
     /**
      * Check the permission to Manage Customers
      *
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Configure.php b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Configure.php
new file mode 100644
index 0000000000000000000000000000000000000000..f70a821c2dc1c876897e8065ea290cf2797a2f52
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Configure.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Wishlist\Product\Composite\Wishlist;
+
+use Exception;
+
+class Configure extends \Magento\Customer\Controller\Adminhtml\Wishlist\Product\Composite\Wishlist
+{
+    /**
+     * Ajax handler to response configuration fieldset of composite product in customer's wishlist.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $configureResult = new \Magento\Framework\Object();
+        try {
+            $this->_initData();
+
+            $configureResult->setProductId($this->_wishlistItem->getProductId());
+            $configureResult->setBuyRequest($this->_wishlistItem->getBuyRequest());
+            $configureResult->setCurrentStoreId($this->_wishlistItem->getStoreId());
+            $configureResult->setCurrentCustomerId($this->_wishlist->getCustomerId());
+
+            $configureResult->setOk(true);
+        } catch (Exception $e) {
+            $configureResult->setError(true);
+            $configureResult->setMessage($e->getMessage());
+        }
+
+        $this->_objectManager->get(
+            'Magento\Catalog\Helper\Product\Composite'
+        )->renderConfigureResult(
+            $configureResult
+        );
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Update.php b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Update.php
new file mode 100644
index 0000000000000000000000000000000000000000..90324371d069d2189985a357e8fc65808c7ed304
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Adminhtml/Wishlist/Product/Composite/Wishlist/Update.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Wishlist\Product\Composite\Wishlist;
+
+use Exception;
+
+class Update extends \Magento\Customer\Controller\Adminhtml\Wishlist\Product\Composite\Wishlist
+{
+    /**
+     * IFrame handler for submitted configuration for wishlist item.
+     *
+     * @return false
+     */
+    public function execute()
+    {
+        // Update wishlist item
+        $updateResult = new \Magento\Framework\Object();
+        try {
+            $this->_initData();
+
+            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
+
+            $this->_wishlist->updateItem($this->_wishlistItem->getId(), $buyRequest)->save();
+
+            $updateResult->setOk(true);
+        } catch (Exception $e) {
+            $updateResult->setError(true);
+            $updateResult->setMessage($e->getMessage());
+        }
+        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
+        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
+        $this->_redirect('catalog/product/showUpdateResult');
+
+        return false;
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Review/Index.php b/app/code/Magento/Customer/Controller/Review/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..88dea9ec004e36dc967360752e92a5ed8d24da07
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Review/Index.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Review;
+
+class Index extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Controller/Review/View.php b/app/code/Magento/Customer/Controller/Review/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..d208a81f7125751e31840aad9603f67070e3946e
--- /dev/null
+++ b/app/code/Magento/Customer/Controller/Review/View.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Review;
+
+class View extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Customer/Model/CustomerExtractor.php b/app/code/Magento/Customer/Model/CustomerExtractor.php
new file mode 100644
index 0000000000000000000000000000000000000000..e82ec9b6215e5f7f4a883a194f2740e8da68d1aa
--- /dev/null
+++ b/app/code/Magento/Customer/Model/CustomerExtractor.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Model;
+
+use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
+use Magento\Framework\App\RequestInterface;
+
+class CustomerExtractor
+{
+    /**
+     * @var \Magento\Customer\Model\Metadata\FormFactory
+     */
+    protected $formFactory;
+
+    /**
+     * @var \Magento\Customer\Service\V1\Data\CustomerBuilder
+     */
+    protected $customerBuilder;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var CustomerGroupServiceInterface
+     */
+    protected $groupService;
+
+    /**
+     * @param Metadata\FormFactory $formFactory
+     * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param CustomerGroupServiceInterface $groupService
+     */
+    public function __construct(
+        \Magento\Customer\Model\Metadata\FormFactory $formFactory,
+        \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        CustomerGroupServiceInterface $groupService
+    ) {
+        $this->formFactory = $formFactory;
+        $this->customerBuilder = $customerBuilder;
+        $this->storeManager = $storeManager;
+        $this->groupService = $groupService;
+    }
+
+    /**
+     * @param string $formCode
+     * @param RequestInterface $request
+     * @return \Magento\Customer\Service\V1\Data\Customer
+     */
+    public function extract($formCode, RequestInterface $request)
+    {
+        $customerForm = $this->formFactory->create('customer', $formCode);
+
+        $allowedAttributes = $customerForm->getAllowedAttributes();
+        $isGroupIdEmpty = true;
+        $customerData = array();
+        foreach ($allowedAttributes as $attribute) {
+            // confirmation in request param is the repeated password, not a confirmation code.
+            if ($attribute === 'confirmation') {
+                continue;
+            }
+            $attributeCode = $attribute->getAttributeCode();
+            if ($attributeCode == 'group_id') {
+                $isGroupIdEmpty = false;
+            }
+            $customerData[$attributeCode] = $request->getParam($attributeCode);
+        }
+        $this->customerBuilder->populateWithArray($customerData);
+        $store = $this->storeManager->getStore();
+        if ($isGroupIdEmpty) {
+            $this->customerBuilder->setGroupId($this->groupService->getDefaultGroup($store->getId())->getId());
+        }
+
+        $this->customerBuilder->setWebsiteId($store->getWebsiteId());
+        $this->customerBuilder->setStoreId($store->getId());
+
+        return $this->customerBuilder->create();
+    }
+}
diff --git a/app/code/Magento/Customer/Model/Resource/Customer/Grid/ServiceCollection.php b/app/code/Magento/Customer/Model/Resource/Customer/Grid/ServiceCollection.php
index e1cd833fa6e8812b628305a2d2051821f316f1ea..a9cd122d15d415cf63f27ff8571a5969677f85e7 100644
--- a/app/code/Magento/Customer/Model/Resource/Customer/Grid/ServiceCollection.php
+++ b/app/code/Magento/Customer/Model/Resource/Customer/Grid/ServiceCollection.php
@@ -24,8 +24,7 @@
 namespace Magento\Customer\Model\Resource\Customer\Grid;
 
 use Magento\Core\Model\EntityFactory;
-use Magento\Customer\Helper\View;
-use Magento\Customer\Model\Resource\AbstractServiceCollection;
+use Magento\Framework\Service\AbstractServiceCollection;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
 use Magento\Customer\Service\V1\Data\CustomerDetails;
 use Magento\Framework\Service\V1\Data\FilterBuilder;
@@ -41,26 +40,20 @@ class ServiceCollection extends AbstractServiceCollection
      */
     protected $accountService;
 
-    /** @var View */
-    protected $viewHelper;
-
     /**
      * @param EntityFactory $entityFactory
      * @param FilterBuilder $filterBuilder
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
      * @param CustomerAccountServiceInterface $accountService
-     * @param View $viewHelper
      */
     public function __construct(
         EntityFactory $entityFactory,
         FilterBuilder $filterBuilder,
         SearchCriteriaBuilder $searchCriteriaBuilder,
-        CustomerAccountServiceInterface $accountService,
-        View $viewHelper
+        CustomerAccountServiceInterface $accountService
     ) {
         parent::__construct($entityFactory, $filterBuilder, $searchCriteriaBuilder);
         $this->accountService = $accountService;
-        $this->viewHelper = $viewHelper;
     }
 
     /**
diff --git a/app/code/Magento/Customer/Model/Resource/Group/Grid/ServiceCollection.php b/app/code/Magento/Customer/Model/Resource/Group/Grid/ServiceCollection.php
index 8f33a64e605f52163b900a6a0b40aa34406d51b7..6307da41ed2e3e18cd7b5a5d09abf53002508725 100644
--- a/app/code/Magento/Customer/Model/Resource/Group/Grid/ServiceCollection.php
+++ b/app/code/Magento/Customer/Model/Resource/Group/Grid/ServiceCollection.php
@@ -24,7 +24,7 @@
 namespace Magento\Customer\Model\Resource\Group\Grid;
 
 use Magento\Core\Model\EntityFactory;
-use Magento\Customer\Model\Resource\AbstractServiceCollection;
+use Magento\Framework\Service\AbstractServiceCollection;
 use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
 use Magento\Customer\Service\V1\Data\CustomerGroup;
 use Magento\Framework\Service\V1\Data\FilterBuilder;
diff --git a/app/code/Magento/Customer/Service/V1/CustomerGroupService.php b/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
index 89bf107adc6bf15b474a15aac0bfcc6bd8c9cb88..90214977d78c755c1a9f2f236b2b377cc2cd6e78 100644
--- a/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
+++ b/app/code/Magento/Customer/Service/V1/CustomerGroupService.php
@@ -36,8 +36,8 @@ use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\StateException;
 use Magento\Framework\Exception\State\InvalidTransitionException;
 use Magento\Framework\Service\V1\Data\SearchCriteria;
-use Magento\Tax\Model\ClassModel as TaxClassModel;
-use Magento\Tax\Model\ClassModelFactory as TaxClassModelFactory;
+use Magento\Tax\Service\V1\Data\TaxClass;
+use Magento\Tax\Service\V1\TaxClassServiceInterface;
 
 /**
  * Customer service is responsible for customer business workflow encapsulation
@@ -72,9 +72,9 @@ class CustomerGroupService implements CustomerGroupServiceInterface
     private $_customerGroupBuilder;
 
     /**
-     * @var TaxClassModelFactory
+     * @var TaxClassServiceInterface
      */
-    private $_taxClassModelFactory;
+    private $_taxClassService;
 
     /**
      * @var GroupRegistry
@@ -92,7 +92,7 @@ class CustomerGroupService implements CustomerGroupServiceInterface
      * @param StoreManagerInterface $storeManager
      * @param Data\SearchResultsBuilder $searchResultsBuilder
      * @param Data\CustomerGroupBuilder $customerGroupBuilder
-     * @param TaxClassModelFactory $taxClassModelFactory
+     * @param TaxClassServiceInterface $taxClassService
      * @param GroupRegistry $groupRegistry
      */
     public function __construct(
@@ -101,7 +101,7 @@ class CustomerGroupService implements CustomerGroupServiceInterface
         StoreManagerInterface $storeManager,
         Data\SearchResultsBuilder $searchResultsBuilder,
         Data\CustomerGroupBuilder $customerGroupBuilder,
-        TaxClassModelFactory $taxClassModelFactory,
+        TaxClassServiceInterface $taxClassService,
         GroupRegistry $groupRegistry
     ) {
         $this->_groupFactory = $groupFactory;
@@ -109,8 +109,8 @@ class CustomerGroupService implements CustomerGroupServiceInterface
         $this->_storeManager = $storeManager;
         $this->_searchResultsBuilder = $searchResultsBuilder;
         $this->_customerGroupBuilder = $customerGroupBuilder;
-        $this->_taxClassModelFactory = $taxClassModelFactory;
         $this->_groupRegistry = $groupRegistry;
+        $this->_taxClassService = $taxClassService;
     }
 
     /**
@@ -312,18 +312,19 @@ class CustomerGroupService implements CustomerGroupServiceInterface
      * Verifies that the tax class model exists and is a customer tax class type.
      *
      * @param int $taxClassId The id of the tax class model to check
-     * @param \Magento\Customer\Service\V1\Data\CustomerGroup $group The original group parameters
+     * @param CustomerGroup $group The original group parameters
      * @return void
      * @throws InputException Thrown if the tax class model is invalid
      */
     protected function _verifyTaxClassModel($taxClassId, $group)
     {
-        /* Doing this until a Tax Service API is available */
-        $taxClassModel = $this->_taxClassModelFactory->create();
-        $taxClassModel->load($taxClassId);
-        if (is_null($taxClassModel->getId())
-            || $taxClassModel->getClassType() !== TaxClassModel::TAX_CLASS_TYPE_CUSTOMER
-            ) {
+        try {
+            /* @var TaxClass $taxClassData */
+            $taxClassData = $this->_taxClassService->getTaxClass($taxClassId);
+        } catch (NoSuchEntityException $e) {
+            throw InputException::invalidFieldValue('taxClassId', $group->getTaxClassId());
+        }
+        if ($taxClassData->getClassType() !== TaxClassServiceInterface::TYPE_CUSTOMER) {
             throw InputException::invalidFieldValue('taxClassId', $group->getTaxClassId());
         }
     }
diff --git a/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php b/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
index 126fc2ec40caf071313e8926792f52312f08515a..fa328ae876bba945d1b0859c595f48b463256512 100644
--- a/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/AddressBuilder.php
@@ -65,6 +65,16 @@ class AddressBuilder extends AbstractObjectBuilder
         $this->_data[Address::KEY_REGION] = $regionBuilder->create();
     }
 
+    /**
+     * Convenience method to return region builder
+     *
+     * @return RegionBuilder
+     */
+    public function getRegionBuilder()
+    {
+        return $this->_regionBuilder;
+    }
+
     /**
      * Set id
      *
diff --git a/app/code/Magento/Customer/Service/V1/Data/SearchResultsBuilder.php b/app/code/Magento/Customer/Service/V1/Data/SearchResultsBuilder.php
index 1557a0cf0bece52ce349e6bbcbf2c51881137897..71425e0c3a32172438f4854939c92f5b092b7439 100644
--- a/app/code/Magento/Customer/Service/V1/Data/SearchResultsBuilder.php
+++ b/app/code/Magento/Customer/Service/V1/Data/SearchResultsBuilder.php
@@ -40,14 +40,14 @@ class SearchResultsBuilder extends AbstractSearchResultsBuilder
      *
      * @param ObjectFactory $objectFactory
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
-     * @param CustomerDetailsBuilder $customerDetailsObjectBuilder
+     * @param CustomerDetailsBuilder $itemObjectBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
         SearchCriteriaBuilder $searchCriteriaBuilder,
-        CustomerDetailsBuilder $customerDetailsObjectBuilder
+        CustomerDetailsBuilder $itemObjectBuilder
     ) {
-        parent::__construct($objectFactory, $searchCriteriaBuilder, $customerDetailsObjectBuilder);
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $itemObjectBuilder);
     }
 
     /**
diff --git a/app/code/Magento/Customer/i18n/de_DE.csv b/app/code/Magento/Customer/i18n/de_DE.csv
index d15d10fd7586b3c7b956ffaad914794deb4b6509..3e4beea48892f32a4479ce96706e598e452e1a29 100644
--- a/app/code/Magento/Customer/i18n/de_DE.csv
+++ b/app/code/Magento/Customer/i18n/de_DE.csv
@@ -183,7 +183,6 @@ Visitor,Besucher
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Falsches Benutzerkonto angegeben."
 "Bad request.","Fehlerhafter Aufruf."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/en_US.csv b/app/code/Magento/Customer/i18n/en_US.csv
index 253ebc2403d272a211ed5b5ef326e71a2f695fe1..750c6cda24723a05a48cc281c2267a9f255e15a4 100644
--- a/app/code/Magento/Customer/i18n/en_US.csv
+++ b/app/code/Magento/Customer/i18n/en_US.csv
@@ -182,7 +182,6 @@ Visitor,Visitor
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Wrong customer account specified."
 "Bad request.","Bad request."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/es_ES.csv b/app/code/Magento/Customer/i18n/es_ES.csv
index 280da69b4f95a23ce47f16eeda0ee17be909ca52..c0299f4a92309244d844f921b5eec6fc96ac0f9c 100644
--- a/app/code/Magento/Customer/i18n/es_ES.csv
+++ b/app/code/Magento/Customer/i18n/es_ES.csv
@@ -182,7 +182,6 @@ Visitor,Visitante
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Se especificó una cuenta de cliente incorrecta."
 "Bad request.","Solicitud incorrecta."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/fr_FR.csv b/app/code/Magento/Customer/i18n/fr_FR.csv
index 964670fab0a5a94083b3a08cdd93c77926493fb0..fd68872af3d29f7129f1b3483df0c66ca16375b2 100644
--- a/app/code/Magento/Customer/i18n/fr_FR.csv
+++ b/app/code/Magento/Customer/i18n/fr_FR.csv
@@ -182,7 +182,6 @@ Visitor,Visiteur
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Mauvais compte utilisateur."
 "Bad request.","Requête invalide."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/nl_NL.csv b/app/code/Magento/Customer/i18n/nl_NL.csv
index 79218e6182923739d05079b07cb67f58fd0d2ec7..c4322feb6924758e2dbb3074bcff64e4e310d68c 100644
--- a/app/code/Magento/Customer/i18n/nl_NL.csv
+++ b/app/code/Magento/Customer/i18n/nl_NL.csv
@@ -182,7 +182,6 @@ Visitor,Bezoeker
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Verkeerde klantaccount opgegeven."
 "Bad request.","Slecht verzoek."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/pt_BR.csv b/app/code/Magento/Customer/i18n/pt_BR.csv
index 45246b543db1cbfc23ea2af84ca8ab1c38ab6c98..ade84e7110e204d42bd94181b2a1c0793c66aa68 100644
--- a/app/code/Magento/Customer/i18n/pt_BR.csv
+++ b/app/code/Magento/Customer/i18n/pt_BR.csv
@@ -182,7 +182,6 @@ Visitor,Visitante
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.","Conta especificada de cliente errada."
 "Bad request.","Mau pedido."
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/i18n/zh_CN.csv b/app/code/Magento/Customer/i18n/zh_CN.csv
index f359f3e759b9571878bf58cb9dc4714a4b795e51..fab9fab5096c278a67b2e0a3e727ddad9a63d271 100644
--- a/app/code/Magento/Customer/i18n/zh_CN.csv
+++ b/app/code/Magento/Customer/i18n/zh_CN.csv
@@ -182,7 +182,6 @@ Visitor,访客
 "Thank you for registering with %1.","Thank you for registering with %1."
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you shipping address for proper VAT calculation"
 "If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation","If you are a registered VAT customer, please click <a href=""%1"">here</a> to enter you billing address for proper VAT calculation"
-"Wrong customer account specified.",指定的客户帐户有误。
 "Bad request.",请求有误。
 "This confirmation key is invalid or has expired.","This confirmation key is invalid or has expired."
 "There was an error confirming the account","There was an error confirming the account"
diff --git a/app/code/Magento/Customer/view/email/account_new.html b/app/code/Magento/Customer/view/email/account_new.html
index 1b9a1b4963566d5cf0ca87de530cf5cb21a0f247..eb1bc032f114854465466fca215eaabb255e7242 100644
--- a/app/code/Magento/Customer/view/email/account_new.html
+++ b/app/code/Magento/Customer/view/email/account_new.html
@@ -32,7 +32,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif;
                                 Use the following values when prompted to log in:<br/>
                                 <strong>E-mail</strong>: {{var customer.email}}<br/>
                                 <strong>Password</strong>: Only you know that! (Hint: It’s the password you created at {{var store.getFrontendName()}})<br/>
-                                Forgot your Account password? No problems. Click <a href="{{store url='customer/account/createpassword/' _query_id=$customer.id _query_token=$customer.rp_token}}">here</a> to reset it.</p>
+                                Forgot your Account password? No problems. Click <a href="{{store url='customer/account/createPassword/' _query_id=$customer.id _query_token=$customer.rp_token}}">here</a> to reset it.</p>
                             </p>
                             <p style="font-size:12px; line-height:16px; margin:0 0 8px 0;">When you log in to your account, you will be able to do the following:</p>
                             <ul style="font-size:12px; line-height:16px; margin:0 0 16px 0; padding:0;">
diff --git a/app/code/Magento/Customer/view/email/account_new_confirmation.html b/app/code/Magento/Customer/view/email/account_new_confirmation.html
index 8162cf3c4a93408a857b511d179f1fdd22ef2071..a9cef3cbfe11e2d315df9445ab66b0b461ff3133 100644
--- a/app/code/Magento/Customer/view/email/account_new_confirmation.html
+++ b/app/code/Magento/Customer/view/email/account_new_confirmation.html
@@ -36,7 +36,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif;
                                 Use the following values when prompted to log in:<br/>
                                 <strong>E-mail:</strong> {{var customer.email}}<br/>
                                 <strong>Password:</strong> Only you know that! (Hint: It’s the password you created at {{var store.getFrontendName()|escape}})<br/>
-                                Forgot your Account password? No problems. Click <a href="{{store url="customer/account/createpassword/" _query_id=$customer.id _query_token=$customer.rp_token}}">here</a> to reset it.
+                                Forgot your Account password? No problems. Click <a href="{{store url="customer/account/createPassword/" _query_id=$customer.id _query_token=$customer.rp_token}}">here</a> to reset it.
                             </p>
                             <p style="font-size:12px; line-height:16px; margin:0;">If you have any questions about your account or any other matter, please feel free to contact us at <a href="mailto:{{config path='trans_email/ident_support/email'}}" style="color:#1E7EC8;">{{config path='trans_email/ident_support/email'}}</a> or by phone at {{config path='general/store_information/phone'}}.</p>
                         </td>
diff --git a/app/code/Magento/Customer/view/email/password_reset_confirmation.html b/app/code/Magento/Customer/view/email/password_reset_confirmation.html
index 08d1281cea55a9c97d08d0687aa5e82875a3da31..9f7de3902e8f27f558a24ea232c0529830c9f215 100644
--- a/app/code/Magento/Customer/view/email/password_reset_confirmation.html
+++ b/app/code/Magento/Customer/view/email/password_reset_confirmation.html
@@ -26,7 +26,7 @@ body,td { color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif;
                             <td valign="top">
                                 <h1 style="font-size: 22px; font-weight: normal; line-height: 22px; margin: 0 0 11px 0;">Dear {{escapehtml var=$customer.name}},</h1>
                                 <p style="font-size: 12px; line-height: 16px; margin: 0 0 8px 0;">There was recently a request to change the password for your account.</p>
-                                <p style="font-size: 12px; line-height: 16px; margin: 0;">If you requested this password change, please click on the following link to reset your password: <a href="{{store url="customer/account/createpassword/" _query_id=$customer.id _query_token=$customer.rp_token}}" style="color:#1E7EC8;">{{store url="customer/account/createpassword/" _query_id=$customer.id _query_token=$customer.rp_token}}</a></p>
+                                <p style="font-size: 12px; line-height: 16px; margin: 0;">If you requested this password change, please click on the following link to reset your password: <a href="{{store url="customer/account/createPassword/" _query_id=$customer.id _query_token=$customer.rp_token}}" style="color:#1E7EC8;">{{store url="customer/account/createPassword/" _query_id=$customer.id _query_token=$customer.rp_token}}</a></p>
                                 <p style="font-size: 12px; line-height: 16px; margin: 0;">If clicking the link does not work, please copy and paste the URL into your browser instead.</p>
                                 <br />
                                 <p style="font-size:12px; line-height:16px; margin:0;">If you did not make this request, you can ignore this message and your password will remain the same.</p>
diff --git a/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index.php b/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportCsv.php
similarity index 73%
rename from app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index.php
rename to app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportCsv.php
index c5a7c5ba225cd0086bf644879bad391eae70c0e6..f8dd56d5e66ce3bac4f97281380491580bbd43f9 100644
--- a/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportCsv.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,12 +22,12 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CustomerImportExport\Controller\Adminhtml;
+namespace Magento\CustomerImportExport\Controller\Adminhtml\Index;
 
 /**
  * Class Index
  */
-class Index extends \Magento\Backend\App\Action
+class ExportCsv extends \Magento\Backend\App\Action
 {
     /**
      * @var \Magento\Framework\App\Response\Http\FileFactory
@@ -52,7 +53,7 @@ class Index extends \Magento\Backend\App\Action
      *
      * @return \Magento\Framework\App\ResponseInterface
      */
-    public function exportCsvAction()
+    public function execute()
     {
         $this->_view->loadLayout();
         $fileName = 'customers.csv';
@@ -64,19 +65,4 @@ class Index extends \Magento\Backend\App\Action
             \Magento\Framework\App\Filesystem::VAR_DIR
         );
     }
-
-    /**
-     * Export customer grid to XML format
-     *
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function exportXmlAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'customers.xml';
-        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('admin.block.customer.grid', 'grid.export');
-        $content = $exportBlock->getExcelFile($fileName);
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
 }
diff --git a/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportXml.php b/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportXml.php
new file mode 100644
index 0000000000000000000000000000000000000000..db0ce66754bba635813632f3672717361cdc5999
--- /dev/null
+++ b/app/code/Magento/CustomerImportExport/Controller/Adminhtml/Index/ExportXml.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CustomerImportExport\Controller\Adminhtml\Index;
+
+/**
+ * Class Index
+ */
+class ExportXml extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * Export customer grid to XML format
+     *
+     * @return \Magento\Framework\App\ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'customers.xml';
+        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('admin.block.customer.grid', 'grid.export');
+        $content = $exportBlock->getExcelFile($fileName);
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
index c3be7c77fd320c8ab764afda9f5852f8527d7d3f..8de26bcd4f4dbcb44f09d833e1e67a296a8e407f 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor.php
@@ -59,306 +59,6 @@ class Editor extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Display the design editor launcher page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        if (!$this->_resolveForwarding()) {
-            $this->_renderStoreDesigner();
-        }
-    }
-
-    /**
-     * Ajax loading available themes
-     *
-     * @return void
-     */
-    public function loadThemeListAction()
-    {
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-
-        $page = $this->getRequest()->getParam('page', 1);
-        $pageSize = $this->getRequest()->getParam(
-            'page_size',
-            \Magento\Core\Model\Resource\Theme\Collection::DEFAULT_PAGE_SIZE
-        );
-
-        try {
-            $this->_view->loadLayout();
-            /** @var $collection \Magento\Core\Model\Resource\Theme\Collection */
-            $collection = $this->_objectManager->get(
-                'Magento\Core\Model\Resource\Theme\Collection'
-            )->filterPhysicalThemes(
-                $page,
-                $pageSize
-            );
-
-            /** @var $availableThemeBlock \Magento\DesignEditor\Block\Adminhtml\Theme\Selector\SelectorList\Available */
-            $availableThemeBlock = $this->_view->getLayout()->getBlock('available.theme.list');
-            $availableThemeBlock->setCollection($collection)->setNextPage(++$page);
-            $availableThemeBlock->setIsFirstEntrance($this->_isFirstEntrance());
-            $availableThemeBlock->setHasThemeAssigned($this->_customizationConfig->hasThemeAssigned());
-
-            $response = array('content' => $this->_view->getLayout()->getOutput());
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response = array('error' => __('Sorry, but we can\'t load the theme list.'));
-        }
-        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
-    }
-
-    /**
-     * Activate the design editor in the session and redirect to the frontend of the selected store
-     *
-     * @return void
-     */
-    public function launchAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        $mode = (string)$this->getRequest()->getParam('mode', \Magento\DesignEditor\Model\State::MODE_NAVIGATION);
-        try {
-            /** @var \Magento\DesignEditor\Model\Theme\Context $themeContext */
-            $themeContext = $this->_objectManager->get('Magento\DesignEditor\Model\Theme\Context');
-            $themeContext->setEditableThemeById($themeId);
-            $launchedTheme = $themeContext->getEditableTheme();
-            if ($launchedTheme->isPhysical()) {
-                $launchedTheme = $launchedTheme->getDomainModel(
-                    ThemeInterface::TYPE_PHYSICAL
-                )->createVirtualTheme(
-                    $launchedTheme
-                );
-                $this->_redirect($this->getUrl('adminhtml/*/*', array('theme_id' => $launchedTheme->getId())));
-                return;
-            }
-            $editableTheme = $themeContext->getStagingTheme();
-
-            $this->_eventManager->dispatch('design_editor_activate');
-
-            $this->_setTitle();
-            $this->_view->loadLayout();
-
-            $this->_configureToolbarBlocks($launchedTheme, $editableTheme, $mode);
-            //top panel
-            $this->_configureToolsBlocks($launchedTheme, $mode);
-            //bottom panel
-            $this->_configureEditorBlock($launchedTheme, $mode);
-            //editor container
-
-            /** @var $storeViewBlock \Magento\DesignEditor\Block\Adminhtml\Theme\Selector\StoreView */
-            $storeViewBlock = $this->_view->getLayout()->getBlock('theme.selector.storeview');
-            $storeViewBlock->setData(array('actionOnAssign' => 'none', 'theme_id' => $launchedTheme->getId()));
-
-            $this->_view->renderLayout();
-        } catch (CoreException $e) {
-            $this->messageManager->addException($e, $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('adminhtml/*/');
-            return;
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Sorry, there was an unknown error.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-    }
-
-    /**
-     * Assign theme to list of store views
-     *
-     * @return void
-     */
-    public function assignThemeToStoreAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        $reportToSession = (bool)$this->getRequest()->getParam('reportToSession');
-
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-
-        $hadThemeAssigned = $this->_customizationConfig->hasThemeAssigned();
-
-        try {
-            $theme = $this->_loadThemeById($themeId);
-
-            $themeCustomization = $theme->isVirtual() ? $theme : $theme->getDomainModel(
-                ThemeInterface::TYPE_PHYSICAL
-            )->createVirtualTheme(
-                $theme
-            );
-
-            /** @var $themeCustomization ThemeInterface */
-            $this->_themeConfig->assignToStore($themeCustomization, $this->_getStores());
-
-            $successMessage = $hadThemeAssigned ? __(
-                'You assigned a new theme to your store view.'
-            ) : __(
-                'You assigned a theme to your live store.'
-            );
-            if ($reportToSession) {
-                $this->messageManager->addSuccess($successMessage);
-            }
-            $response = array('message' => $successMessage, 'themeId' => $themeCustomization->getId());
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response = array('error' => true, 'message' => __('This theme is not assigned.'));
-        }
-        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
-    }
-
-    /**
-     * Rename title action
-     *
-     * @return void
-     */
-    public function quickEditAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        $themeTitle = (string)$this->getRequest()->getParam('theme_title');
-
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-        try {
-            $theme = $this->_loadThemeById($themeId);
-            if (!$theme->isEditable()) {
-                throw new CoreException(__('Sorry, but you can\'t edit theme "%1".', $theme->getThemeTitle()));
-            }
-            $theme->setThemeTitle($themeTitle);
-            $theme->save();
-            $response = array('success' => true);
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response = array('error' => true, 'message' => __('This theme is not saved.'));
-        }
-        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
-    }
-
-    /**
-     * Display available theme list. Only when no customized themes
-     *
-     * @return void
-     */
-    public function firstEntranceAction()
-    {
-        if (!$this->_resolveForwarding()) {
-            $this->_renderStoreDesigner();
-        }
-    }
-
-    /**
-     * Apply changes from 'staging' theme to 'virtual' theme
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-
-        /** @var \Magento\DesignEditor\Model\Theme\Context $themeContext */
-        $themeContext = $this->_objectManager->get('Magento\DesignEditor\Model\Theme\Context');
-        $themeContext->setEditableThemeById($themeId);
-        try {
-            $themeContext->copyChanges();
-            if ($this->_customizationConfig->isThemeAssignedToStore($themeContext->getEditableTheme())) {
-                $message = __('You updated your live store.');
-            } else {
-                $message = __('You saved updates to this theme.');
-            }
-            $response = array('message' => $message);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response = array('error' => true, 'message' => __('Sorry, there was an unknown error.'));
-        }
-
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
-    }
-
-    /**
-     * Duplicate theme action
-     *
-     * @return void
-     */
-    public function duplicateAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        /** @var $themeCopy ThemeInterface */
-        $themeCopy = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
-        /** @var $copyService \Magento\Theme\Model\CopyService */
-        $copyService = $this->_objectManager->get('Magento\Theme\Model\CopyService');
-        try {
-            $theme = $this->_loadThemeById($themeId);
-            if (!$theme->isVirtual()) {
-                throw new CoreException(__('Sorry, but you can\'t edit theme "%1".', $theme->getThemeTitle()));
-            }
-            $themeCopy->setData($theme->getData());
-            $themeCopy->setId(null)->setThemeTitle(__('Copy of [%1]', $theme->getThemeTitle()));
-            $themeCopy->getThemeImage()->createPreviewImageCopy($theme);
-            $themeCopy->save();
-            $copyService->copy($theme, $themeCopy);
-            $this->messageManager->addSuccess(__('You saved a duplicate copy of this theme in "My Customizations."'));
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__('You cannot duplicate this theme.'));
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-    }
-
-    /**
-     * Revert 'staging' theme to the state of 'physical' or 'virtual'
-     *
-     * @return void
-     * @throws CoreException
-     */
-    public function revertAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        $revertTo = $this->getRequest()->getParam('revert_to');
-
-        $virtualTheme = $this->_loadThemeById($themeId);
-        if (!$virtualTheme->isVirtual()) {
-            throw new CoreException(__('Theme "%1" is not editable.', $virtualTheme->getId()));
-        }
-
-        try {
-            /** @var $copyService \Magento\Theme\Model\CopyService */
-            $copyService = $this->_objectManager->get('Magento\Theme\Model\CopyService');
-            $stagingTheme = $virtualTheme->getDomainModel(ThemeInterface::TYPE_VIRTUAL)->getStagingTheme();
-            switch ($revertTo) {
-                case 'last_saved':
-                    $copyService->copy($virtualTheme, $stagingTheme);
-                    $message = __('Theme "%1" reverted to last saved state', $virtualTheme->getThemeTitle());
-                    break;
-
-                case 'physical':
-                    $physicalTheme = $virtualTheme->getDomainModel(ThemeInterface::TYPE_VIRTUAL)->getPhysicalTheme();
-                    $copyService->copy($physicalTheme, $stagingTheme);
-                    $message = __('Theme "%1" reverted to last default state', $virtualTheme->getThemeTitle());
-                    break;
-
-                default:
-                    throw new \Magento\Framework\Exception('Invalid revert mode "%s"', $revertTo);
-            }
-            $response = array('message' => $message);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response = array('error' => true, 'message' => __('Unknown error'));
-        }
-        /** @var $coreHelper \Magento\Core\Helper\Data */
-        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
-        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
-    }
-
     /**
      * Set page title
      *
@@ -397,85 +97,6 @@ class Editor extends \Magento\Backend\App\Action
         return $this->_authorization->isAllowed('Magento_DesignEditor::editor');
     }
 
-    /**
-     * Pass data to the Tools panel blocks that is needed it for rendering
-     *
-     * @param ThemeInterface $theme
-     * @param string $mode
-     * @return $this
-     */
-    protected function _configureToolsBlocks($theme, $mode)
-    {
-        /** @var $toolsBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Tools */
-        $toolsBlock = $this->_view->getLayout()->getBlock('design_editor_tools');
-        if ($toolsBlock) {
-            $toolsBlock->setMode($mode);
-        }
-
-        /** @var $cssTabBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Css */
-        $cssTabBlock = $this->_view->getLayout()->getBlock('design_editor_tools_code_css');
-        if ($cssTabBlock) {
-            /** @var $helper \Magento\Core\Helper\Theme */
-            $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
-            $assets = $helper->getCssAssets($theme);
-            $cssTabBlock->setAssets($assets)
-                ->setThemeId($theme->getId());
-        }
-        return $this;
-    }
-
-    /**
-     * Pass data to the Toolbar panel blocks that is needed for rendering
-     *
-     * @param ThemeInterface $theme
-     * @param ThemeInterface $editableTheme
-     * @param string $mode
-     * @return $this
-     */
-    protected function _configureToolbarBlocks($theme, $editableTheme, $mode)
-    {
-        /** @var $toolbarBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons */
-        $toolbarBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons');
-        $toolbarBlock->setThemeId($editableTheme->getId())->setVirtualThemeId($theme->getId())->setMode($mode);
-
-        /** @var $saveButtonBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Save */
-        $saveButtonBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons_save');
-        if ($saveButtonBlock) {
-            $saveButtonBlock->setTheme(
-                $theme
-            )->setMode(
-                $mode
-            )->setHasThemeAssigned(
-                $this->_customizationConfig->hasThemeAssigned()
-            );
-        }
-        /** @var $saveButtonBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Edit */
-        $editButtonBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons_edit');
-        if ($editButtonBlock) {
-            $editButtonBlock->setTheme($editableTheme);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Set to iframe block selected mode and theme
-     *
-     * @param ThemeInterface $editableTheme
-     * @param string $mode
-     * @return $this
-     */
-    protected function _configureEditorBlock($editableTheme, $mode)
-    {
-        /** @var $editorBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Container */
-        $editorBlock = $this->_view->getLayout()->getBlock('design_editor');
-        $currentUrl = $this->_getCurrentUrl($editableTheme->getId(), $mode);
-        $editorBlock->setFrameUrl($currentUrl);
-        $editorBlock->setTheme($editableTheme);
-
-        return $this;
-    }
-
     /**
      * Check whether is customized themes in database
      *
@@ -540,55 +161,4 @@ class Editor extends \Magento\Backend\App\Action
 
         return false;
     }
-
-    /**
-     * Get current url
-     *
-     * @param null|string $themeId
-     * @param null|string $mode
-     * @return string
-     */
-    protected function _getCurrentUrl($themeId = null, $mode = null)
-    {
-        /** @var $vdeUrlModel \Magento\DesignEditor\Model\Url\NavigationMode */
-        $vdeUrlModel = $this->_objectManager->create(
-            'Magento\DesignEditor\Model\Url\NavigationMode',
-            array('data' => array('mode' => $mode, 'themeId' => $themeId))
-        );
-        $url = $this->_getSession()->getData(\Magento\DesignEditor\Model\State::CURRENT_URL_SESSION_KEY);
-        if (empty($url)) {
-            $url = '';
-        }
-        return $vdeUrlModel->getUrl(ltrim($url, '/'));
-    }
-
-    /**
-     * Get stores
-     *
-     * @todo temporary method. used until we find a way to convert array to JSON on JS side
-     *
-     * @return Store[]
-     * @throws \InvalidArgumentException
-     */
-    protected function _getStores()
-    {
-        $stores = $this->getRequest()->getParam('stores');
-
-        $defaultStore = -1;
-        $emptyStores = -2;
-        if ($stores == $defaultStore) {
-            /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */
-            $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
-            $ids = array_keys($storeManager->getStores());
-            $stores = array(array_shift($ids));
-        } elseif ($stores == $emptyStores) {
-            $stores = array();
-        }
-
-        if (!is_array($stores)) {
-            throw new \InvalidArgumentException('Param "stores" is not valid');
-        }
-
-        return $stores;
-    }
 }
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
new file mode 100644
index 0000000000000000000000000000000000000000..889a71cb75d9f1ce65c31318757a0ecc46e7b422
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/AssignThemeToStore.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+use Magento\Store\Model\Store;
+use Magento\Framework\View\Design\ThemeInterface;
+
+class AssignThemeToStore extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Get stores
+     *
+     * @todo temporary method. used until we find a way to convert array to JSON on JS side
+     *
+     * @return Store[]
+     * @throws \InvalidArgumentException
+     */
+    protected function _getStores()
+    {
+        $stores = $this->getRequest()->getParam('stores');
+
+        $defaultStore = -1;
+        $emptyStores = -2;
+        if ($stores == $defaultStore) {
+            /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */
+            $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
+            $ids = array_keys($storeManager->getStores());
+            $stores = array(array_shift($ids));
+        } elseif ($stores == $emptyStores) {
+            $stores = array();
+        }
+
+        if (!is_array($stores)) {
+            throw new \InvalidArgumentException('Param "stores" is not valid');
+        }
+
+        return $stores;
+    }
+
+    /**
+     * Assign theme to list of store views
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        $reportToSession = (bool)$this->getRequest()->getParam('reportToSession');
+
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+
+        $hadThemeAssigned = $this->_customizationConfig->hasThemeAssigned();
+
+        try {
+            $theme = $this->_loadThemeById($themeId);
+
+            $themeCustomization = $theme->isVirtual() ? $theme : $theme->getDomainModel(
+                ThemeInterface::TYPE_PHYSICAL
+            )->createVirtualTheme(
+                $theme
+            );
+
+            /** @var $themeCustomization ThemeInterface */
+            $this->_themeConfig->assignToStore($themeCustomization, $this->_getStores());
+
+            $successMessage = $hadThemeAssigned ? __(
+                'You assigned a new theme to your store view.'
+            ) : __(
+                'You assigned a theme to your live store.'
+            );
+            if ($reportToSession) {
+                $this->messageManager->addSuccess($successMessage);
+            }
+            $response = array('message' => $successMessage, 'themeId' => $themeCustomization->getId());
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response = array('error' => true, 'message' => __('This theme is not assigned.'));
+        }
+        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
new file mode 100644
index 0000000000000000000000000000000000000000..5904dc7506cec94c7ab1ee28bf0e8adc2e4b0607
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Duplicate.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+use Magento\Framework\Model\Exception as CoreException;
+use Magento\Framework\View\Design\ThemeInterface;
+
+class Duplicate extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Duplicate theme action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        /** @var $themeCopy ThemeInterface */
+        $themeCopy = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
+        /** @var $copyService \Magento\Theme\Model\CopyService */
+        $copyService = $this->_objectManager->get('Magento\Theme\Model\CopyService');
+        try {
+            $theme = $this->_loadThemeById($themeId);
+            if (!$theme->isVirtual()) {
+                throw new CoreException(__('Sorry, but you can\'t edit theme "%1".', $theme->getThemeTitle()));
+            }
+            $themeCopy->setData($theme->getData());
+            $themeCopy->setId(null)->setThemeTitle(__('Copy of [%1]', $theme->getThemeTitle()));
+            $themeCopy->getThemeImage()->createPreviewImageCopy($theme);
+            $themeCopy->save();
+            $copyService->copy($theme, $themeCopy);
+            $this->messageManager->addSuccess(__('You saved a duplicate copy of this theme in "My Customizations."'));
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__('You cannot duplicate this theme.'));
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Contents.php
similarity index 65%
rename from app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php
rename to app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Contents.php
index 5024da14ad9981dbf0b0c7026811cd938039c5ed..256202406e135adef11bf2b30d0c7d28c7863d54 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Contents.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,42 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
 
-/**
- * Files controller
- */
-class Files extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+class Contents extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
 {
-    /**
-     * Tree json action
-     *
-     * @return void
-     */
-    public function treeJsonAction()
-    {
-        try {
-            $this->getResponse()->representJson(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Files\Tree'
-                )->getTreeJson(
-                    $this->_getStorage()->getTreeArray()
-                )
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())
-            );
-        }
-    }
-
     /**
      * Contents action
      *
      * @return void
      */
-    public function contentsAction()
+    public function execute()
     {
         try {
             $this->_view->loadLayout('empty');
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFiles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..87dada452b4c9d642459878565c283e1df067ea5
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFiles.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class DeleteFiles extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\DeleteFiles
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFolder.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..a677f5acb19d42c995f9ba7200efb5741487341e
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/DeleteFolder.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class DeleteFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\DeleteFolder
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Index.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..23a8f68804505f6abb8b9b854dc717afbd8eb834
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class Index extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\Index
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/NewFolder.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/NewFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..6415557e1cbb76dd40300320203b75179e1d1a00
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/NewFolder.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class NewFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\NewFolder
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/OnInsert.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/OnInsert.php
new file mode 100644
index 0000000000000000000000000000000000000000..264f31e589c2b4f7b6370a67fdfce1465e6e7568
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/OnInsert.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class OnInsert extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\OnInsert
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/PreviewImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/PreviewImage.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5860bebf5641808246b4b5dc86f689d2ea48725
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/PreviewImage.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class PreviewImage extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\PreviewImage
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d057cc8584325439ef315145b517b8cf58e6f40
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/TreeJson.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Tree json action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getResponse()->representJson(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Files\Tree'
+                )->getTreeJson(
+                    $this->_getStorage()->getTreeArray()
+                )
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Upload.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..19ea9aabbd9c81e5eb52d11a1f29b8d32b9a4619
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Files/Upload.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Files;
+
+class Upload extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files\Upload
+{
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntrance.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntrance.php
new file mode 100644
index 0000000000000000000000000000000000000000..71aa034b10c252c087cf22e4058b58f111ce569e
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntrance.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+class FirstEntrance extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Display available theme list. Only when no customized themes
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_resolveForwarding()) {
+            $this->_renderStoreDesigner();
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Index.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..70fea9085523563a0aad209da397451fbe670e4e
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Index.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+class Index extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Display the design editor launcher page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_resolveForwarding()) {
+            $this->_renderStoreDesigner();
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
new file mode 100644
index 0000000000000000000000000000000000000000..e582a7a37e567f16db83f75b70668944f6909dc6
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Launch.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+use Magento\Framework\Model\Exception as CoreException;
+use Magento\Framework\View\Design\ThemeInterface;
+
+class Launch extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Pass data to the Tools panel blocks that is needed it for rendering
+     *
+     * @param ThemeInterface $theme
+     * @param string $mode
+     * @return $this
+     */
+    protected function _configureToolsBlocks($theme, $mode)
+    {
+        /** @var $toolsBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Tools */
+        $toolsBlock = $this->_view->getLayout()->getBlock('design_editor_tools');
+        if ($toolsBlock) {
+            $toolsBlock->setMode($mode);
+        }
+
+        /** @var $cssTabBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Css */
+        $cssTabBlock = $this->_view->getLayout()->getBlock('design_editor_tools_code_css');
+        if ($cssTabBlock) {
+            /** @var $helper \Magento\Core\Helper\Theme */
+            $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
+            $assets = $helper->getCssAssets($theme);
+            $cssTabBlock->setAssets($assets)
+                ->setThemeId($theme->getId());
+        }
+        return $this;
+    }
+
+    /**
+     * Set to iframe block selected mode and theme
+     *
+     * @param ThemeInterface $editableTheme
+     * @param string $mode
+     * @return $this
+     */
+    protected function _configureEditorBlock($editableTheme, $mode)
+    {
+        /** @var $editorBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Container */
+        $editorBlock = $this->_view->getLayout()->getBlock('design_editor');
+        $currentUrl = $this->_getCurrentUrl($editableTheme->getId(), $mode);
+        $editorBlock->setFrameUrl($currentUrl);
+        $editorBlock->setTheme($editableTheme);
+
+        return $this;
+    }
+
+    /**
+     * Pass data to the Toolbar panel blocks that is needed for rendering
+     *
+     * @param ThemeInterface $theme
+     * @param ThemeInterface $editableTheme
+     * @param string $mode
+     * @return $this
+     */
+    protected function _configureToolbarBlocks($theme, $editableTheme, $mode)
+    {
+        /** @var $toolbarBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons */
+        $toolbarBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons');
+        $toolbarBlock->setThemeId($editableTheme->getId())->setVirtualThemeId($theme->getId())->setMode($mode);
+
+        /** @var $saveButtonBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Save */
+        $saveButtonBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons_save');
+        if ($saveButtonBlock) {
+            $saveButtonBlock->setTheme(
+                $theme
+            )->setMode(
+                $mode
+            )->setHasThemeAssigned(
+                $this->_customizationConfig->hasThemeAssigned()
+            );
+        }
+        /** @var $saveButtonBlock \Magento\DesignEditor\Block\Adminhtml\Editor\Toolbar\Buttons\Edit */
+        $editButtonBlock = $this->_view->getLayout()->getBlock('design_editor_toolbar_buttons_edit');
+        if ($editButtonBlock) {
+            $editButtonBlock->setTheme($editableTheme);
+        }
+
+        return $this;
+    }
+
+    /**
+     * Get current url
+     *
+     * @param null|string $themeId
+     * @param null|string $mode
+     * @return string
+     */
+    protected function _getCurrentUrl($themeId = null, $mode = null)
+    {
+        /** @var $vdeUrlModel \Magento\DesignEditor\Model\Url\NavigationMode */
+        $vdeUrlModel = $this->_objectManager->create(
+            'Magento\DesignEditor\Model\Url\NavigationMode',
+            array('data' => array('mode' => $mode, 'themeId' => $themeId))
+        );
+        $url = $this->_getSession()->getData(\Magento\DesignEditor\Model\State::CURRENT_URL_SESSION_KEY);
+        if (empty($url)) {
+            $url = '';
+        }
+        return $vdeUrlModel->getUrl(ltrim($url, '/'));
+    }
+
+    /**
+     * Activate the design editor in the session and redirect to the frontend of the selected store
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        $mode = (string)$this->getRequest()->getParam('mode', \Magento\DesignEditor\Model\State::MODE_NAVIGATION);
+        try {
+            /** @var \Magento\DesignEditor\Model\Theme\Context $themeContext */
+            $themeContext = $this->_objectManager->get('Magento\DesignEditor\Model\Theme\Context');
+            $themeContext->setEditableThemeById($themeId);
+            $launchedTheme = $themeContext->getEditableTheme();
+            if ($launchedTheme->isPhysical()) {
+                $launchedTheme = $launchedTheme->getDomainModel(
+                    ThemeInterface::TYPE_PHYSICAL
+                )->createVirtualTheme(
+                    $launchedTheme
+                );
+                $this->_redirect($this->getUrl('adminhtml/*/*', array('theme_id' => $launchedTheme->getId())));
+                return;
+            }
+            $editableTheme = $themeContext->getStagingTheme();
+
+            $this->_eventManager->dispatch('design_editor_activate');
+
+            $this->_setTitle();
+            $this->_view->loadLayout();
+
+            $this->_configureToolbarBlocks($launchedTheme, $editableTheme, $mode);
+            //top panel
+            $this->_configureToolsBlocks($launchedTheme, $mode);
+            //bottom panel
+            $this->_configureEditorBlock($launchedTheme, $mode);
+            //editor container
+
+            /** @var $storeViewBlock \Magento\DesignEditor\Block\Adminhtml\Theme\Selector\StoreView */
+            $storeViewBlock = $this->_view->getLayout()->getBlock('theme.selector.storeview');
+            $storeViewBlock->setData(array('actionOnAssign' => 'none', 'theme_id' => $launchedTheme->getId()));
+
+            $this->_view->renderLayout();
+        } catch (CoreException $e) {
+            $this->messageManager->addException($e, $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('adminhtml/*/');
+            return;
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Sorry, there was an unknown error.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
new file mode 100644
index 0000000000000000000000000000000000000000..12276e713473038ebfad59e38c9de67ca1cf7d85
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/LoadThemeList.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+class LoadThemeList extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Ajax loading available themes
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+
+        $page = $this->getRequest()->getParam('page', 1);
+        $pageSize = $this->getRequest()->getParam(
+            'page_size',
+            \Magento\Core\Model\Resource\Theme\Collection::DEFAULT_PAGE_SIZE
+        );
+
+        try {
+            $this->_view->loadLayout();
+            /** @var $collection \Magento\Core\Model\Resource\Theme\Collection */
+            $collection = $this->_objectManager->get(
+                'Magento\Core\Model\Resource\Theme\Collection'
+            )->filterPhysicalThemes(
+                $page,
+                $pageSize
+            );
+
+            /** @var $availableThemeBlock \Magento\DesignEditor\Block\Adminhtml\Theme\Selector\SelectorList\Available */
+            $availableThemeBlock = $this->_view->getLayout()->getBlock('available.theme.list');
+            $availableThemeBlock->setCollection($collection)->setNextPage(++$page);
+            $availableThemeBlock->setIsFirstEntrance($this->_isFirstEntrance());
+            $availableThemeBlock->setHasThemeAssigned($this->_customizationConfig->hasThemeAssigned());
+
+            $response = array('content' => $this->_view->getLayout()->getOutput());
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response = array('error' => __('Sorry, but we can\'t load the theme list.'));
+        }
+        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc797c1d8a5b91f187ccd2c3049986ba8b2067ca
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/QuickEdit.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class QuickEdit extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Rename title action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        $themeTitle = (string)$this->getRequest()->getParam('theme_title');
+
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+        try {
+            $theme = $this->_loadThemeById($themeId);
+            if (!$theme->isEditable()) {
+                throw new CoreException(__('Sorry, but you can\'t edit theme "%1".', $theme->getThemeTitle()));
+            }
+            $theme->setThemeTitle($themeTitle);
+            $theme->save();
+            $response = array('success' => true);
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response = array('error' => true, 'message' => __('This theme is not saved.'));
+        }
+        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
new file mode 100644
index 0000000000000000000000000000000000000000..110ac456f5663b96a7712850f3506d53cb7b3ae8
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Revert.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+use Magento\Framework\Model\Exception as CoreException;
+use Magento\Framework\View\Design\ThemeInterface;
+
+class Revert extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Revert 'staging' theme to the state of 'physical' or 'virtual'
+     *
+     * @return void
+     * @throws CoreException
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        $revertTo = $this->getRequest()->getParam('revert_to');
+
+        $virtualTheme = $this->_loadThemeById($themeId);
+        if (!$virtualTheme->isVirtual()) {
+            throw new CoreException(__('Theme "%1" is not editable.', $virtualTheme->getId()));
+        }
+
+        try {
+            /** @var $copyService \Magento\Theme\Model\CopyService */
+            $copyService = $this->_objectManager->get('Magento\Theme\Model\CopyService');
+            $stagingTheme = $virtualTheme->getDomainModel(ThemeInterface::TYPE_VIRTUAL)->getStagingTheme();
+            switch ($revertTo) {
+                case 'last_saved':
+                    $copyService->copy($virtualTheme, $stagingTheme);
+                    $message = __('Theme "%1" reverted to last saved state', $virtualTheme->getThemeTitle());
+                    break;
+
+                case 'physical':
+                    $physicalTheme = $virtualTheme->getDomainModel(ThemeInterface::TYPE_VIRTUAL)->getPhysicalTheme();
+                    $copyService->copy($physicalTheme, $stagingTheme);
+                    $message = __('Theme "%1" reverted to last default state', $virtualTheme->getThemeTitle());
+                    break;
+
+                default:
+                    throw new \Magento\Framework\Exception('Invalid revert mode "%s"', $revertTo);
+            }
+            $response = array('message' => $message);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response = array('error' => true, 'message' => __('Unknown error'));
+        }
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec73cffb079ec4d2521337ca2a8d4889ad0c97ba
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Save.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+class Save extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+{
+    /**
+     * Apply changes from 'staging' theme to 'virtual' theme
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+
+        /** @var \Magento\DesignEditor\Model\Theme\Context $themeContext */
+        $themeContext = $this->_objectManager->get('Magento\DesignEditor\Model\Theme\Context');
+        $themeContext->setEditableThemeById($themeId);
+        try {
+            $themeContext->copyChanges();
+            if ($this->_customizationConfig->isThemeAssignedToStore($themeContext->getEditableTheme())) {
+                $message = __('You updated your live store.');
+            } else {
+                $message = __('You saved updates to this theme.');
+            }
+            $response = array('message' => $message);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response = array('error' => true, 'message' => __('Sorry, there was an unknown error.'));
+        }
+
+        /** @var $coreHelper \Magento\Core\Helper\Data */
+        $coreHelper = $this->_objectManager->get('Magento\Core\Helper\Data');
+        $this->getResponse()->representJson($coreHelper->jsonEncode($response));
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php
index bacd1b8d584651dcd394552babe00c12accc6f11..8934c44aea7f58195e6fce803f87ac5018575b66 100644
--- a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools.php
@@ -23,8 +23,6 @@
  */
 namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
 
-use Magento\Framework\Model\Exception as CoreException;
-
 /**
  * Backend controller for the design editor
  *
@@ -45,450 +43,6 @@ class Tools extends \Magento\Backend\App\Action
         return $themeContext->setEditableThemeById($themeId);
     }
 
-    /**
-     * Upload custom CSS action
-     *
-     * @return void
-     */
-    public function uploadAction()
-    {
-        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
-        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
-        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
-        $singleFile = $this->_objectManager->create(
-            'Magento\Theme\Model\Theme\SingleFile',
-            array('fileService' => $cssService)
-        );
-        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
-        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $cssFileData = $serviceModel->uploadCssFile(
-                \Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Custom::FILE_ELEMENT_NAME
-            );
-            $singleFile->update($editableTheme, $cssFileData['content']);
-            $response = array(
-                'success' => true,
-                'message' => __('You updated the custom.css file.'),
-                'content' => $cssFileData['content']
-            );
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Save custom css file
-     *
-     * @return void
-     */
-    public function saveCssContentAction()
-    {
-        $customCssContent = (string)$this->getRequest()->getParam('custom_css_content', '');
-        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
-        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
-        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
-        $singleFile = $this->_objectManager->create(
-            'Magento\Theme\Model\Theme\SingleFile',
-            array('fileService' => $cssService)
-        );
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $customCss = $singleFile->update($editableTheme, $customCssContent);
-            $response = array(
-                'success' => true,
-                'filename' => $customCss->getFileName(),
-                'message' => __('You updated the %1 file.', $customCss->getFileName())
-            );
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('We can\'t save the custom css file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Ajax list of existing javascript files
-     *
-     * @return void
-     */
-    public function jsListAction()
-    {
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $customization = $editableTheme->getCustomization();
-            $customJsFiles = $customization->getFilesByType(\Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE);
-            $result = array('error' => false, 'files' => $customization->generateFileInfo($customJsFiles));
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Upload js file
-     *
-     * @return void
-     */
-    public function uploadJsAction()
-    {
-        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
-        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
-        /** @var $jsService \Magento\Framework\View\Design\Theme\Customization\File\Js */
-        $jsService = $this->_objectManager->create('Magento\Framework\View\Design\Theme\Customization\File\Js');
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $jsFileData = $serviceModel->uploadJsFile('js_files_uploader');
-            $jsFile = $jsService->create();
-            $jsFile->setTheme($editableTheme);
-            $jsFile->setFileName($jsFileData['filename']);
-            $jsFile->setData('content', $jsFileData['content']);
-            $jsFile->save();
-            $this->_forward('jsList');
-            return;
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('We cannot upload the JS file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Delete custom file action
-     *
-     * @return void
-     */
-    public function deleteCustomFilesAction()
-    {
-        $removeJsFiles = (array)$this->getRequest()->getParam('js_removed_files');
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $editableTheme->getCustomization()->delete($removeJsFiles);
-            $this->_forward('jsList');
-        } catch (\Exception $e) {
-            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Reorder js file
-     *
-     * @return void
-     */
-    public function reorderJsAction()
-    {
-        $reorderJsFiles = (array)$this->getRequest()->getParam('js_order', array());
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $editableTheme->getCustomization()->reorder(
-                \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE,
-                $reorderJsFiles
-            );
-            $result = array('success' => true);
-        } catch (CoreException $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Save image sizes
-     *
-     * @return void
-     */
-    public function saveImageSizingAction()
-    {
-        $imageSizing = $this->getRequest()->getParam('imagesizing');
-        /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
-        $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
-        /** @var $imageSizingValidator \Magento\DesignEditor\Model\Editor\Tools\ImageSizing\Validator */
-        $imageSizingValidator = $this->_objectManager->get(
-            'Magento\DesignEditor\Model\Editor\Tools\ImageSizing\Validator'
-        );
-        try {
-            $themeContext = $this->_initContext();
-            $configuration = $configFactory->create(
-                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_IMAGE_SIZING,
-                $themeContext->getStagingTheme(),
-                $themeContext->getEditableTheme()->getParentTheme()
-            );
-            $imageSizing = $imageSizingValidator->validate($configuration->getAllControlsData(), $imageSizing);
-            $configuration->saveData($imageSizing);
-            $result = array('success' => true, 'message' => __('We saved the image sizes.'));
-        } catch (CoreException $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => __('We can\'t save image sizes.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Upload quick style image
-     *
-     * @return void
-     */
-    public function uploadQuickStyleImageAction()
-    {
-        /** @var $uploaderModel \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader */
-        $uploaderModel = $this->_objectManager->get(
-            'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader'
-        );
-        try {
-            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
-            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $keys = array_keys($this->getRequest()->getFiles());
-            $result = $uploaderModel->setTheme($editableTheme)->uploadFile($keys[0]);
-
-            $configuration = $configFactory->create(
-                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
-                $editableTheme,
-                $themeContext->getEditableTheme()->getParentTheme()
-            );
-            $configuration->saveData(array($keys[0] => $result['css_path']));
-
-            $response = array('error' => false, 'content' => $result);
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $errorMessage = __(
-                'Something went wrong uploading the image.' .
-                ' Please check the file format and try again (JPEG, GIF, or PNG).'
-            );
-            $response = array('error' => true, 'message' => $errorMessage);
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Remove quick style image
-     *
-     * @return void
-     */
-    public function removeQuickStyleImageAction()
-    {
-        $fileName = $this->getRequest()->getParam('file_name', false);
-        $elementName = $this->getRequest()->getParam('element', false);
-
-        /** @var $uploaderModel \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader */
-        $uploaderModel = $this->_objectManager->get(
-            'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader'
-        );
-        try {
-            $themeContext = $this->_initContext();
-            $editableTheme = $themeContext->getStagingTheme();
-            $result = $uploaderModel->setTheme($editableTheme)->removeFile($fileName);
-
-            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
-            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
-
-            $configuration = $configFactory->create(
-                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
-                $editableTheme,
-                $themeContext->getEditableTheme()->getParentTheme()
-            );
-            $configuration->saveData(array($elementName => ''));
-
-            $response = array('error' => false, 'content' => $result);
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $errorMessage = __(
-                'Something went wrong uploading the image.' .
-                ' Please check the file format and try again (JPEG, GIF, or PNG).'
-            );
-            $response = array('error' => true, 'message' => $errorMessage);
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Upload store logo
-     *
-     * @return void
-     * @throws CoreException
-     */
-    public function uploadStoreLogoAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store_id');
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        try {
-            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
-            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
-            if (!$theme->load($themeId)->getId() || !$theme->isEditable()) {
-                throw new CoreException(__('The file can\'t be found or edited.'));
-            }
-
-            /** @var $customizationConfig \Magento\Theme\Model\Config\Customization */
-            $customizationConfig = $this->_objectManager->get('Magento\Theme\Model\Config\Customization');
-            $store = $this->_objectManager->get('Magento\Store\Model\Store')->load($storeId);
-
-            if (!$customizationConfig->isThemeAssignedToStore($theme, $store)) {
-                throw new CoreException(__('This theme is not assigned to a store view #%1.', $theme->getId()));
-            }
-            /** @var $storeLogo \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\LogoUploader */
-            $storeLogo = $this->_objectManager->get(
-                'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\LogoUploader'
-            );
-            $storeLogo->setScope('stores')->setScopeId($store->getId())->setPath('design/header/logo_src')->save();
-
-            $this->_reinitSystemConfiguration();
-
-            $response = array('error' => false, 'content' => array('name' => basename($storeLogo->getValue())));
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $errorMessage = __(
-                'Something went wrong uploading the image.' .
-                ' Please check the file format and try again (JPEG, GIF, or PNG).'
-            );
-            $response = array('error' => true, 'message' => $errorMessage);
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Remove store logo
-     *
-     * @return void
-     * @throws CoreException
-     */
-    public function removeStoreLogoAction()
-    {
-        $storeId = (int)$this->getRequest()->getParam('store_id');
-        $themeId = (int)$this->getRequest()->getParam('theme_id');
-        try {
-            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
-            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
-            if (!$theme->load($themeId)->getId() || !$theme->isEditable()) {
-                throw new CoreException(__('The file can\'t be found or edited.'));
-            }
-
-            /** @var $customizationConfig \Magento\Theme\Model\Config\Customization */
-            $customizationConfig = $this->_objectManager->get('Magento\Theme\Model\Config\Customization');
-            $store = $this->_objectManager->get('Magento\Store\Model\Store')->load($storeId);
-
-            if (!$customizationConfig->isThemeAssignedToStore($theme, $store)) {
-                throw new CoreException(__('This theme is not assigned to a store view #%1.', $theme->getId()));
-            }
-
-            $this->_objectManager->get(
-                'Magento\Backend\Model\Config\Backend\Store'
-            )->setScope(
-                'stores'
-            )->setScopeId(
-                $store->getId()
-            )->setPath(
-                'design/header/logo_src'
-            )->setValue(
-                ''
-            )->save();
-
-            $this->_reinitSystemConfiguration();
-            $response = array('error' => false, 'content' => array());
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $errorMessage = __(
-                'Something went wrong uploading the image.' .
-                ' Please check the file format and try again (JPEG, GIF, or PNG).'
-            );
-            $response = array('error' => true, 'message' => $errorMessage);
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
-    /**
-     * Save quick styles data
-     *
-     * @return void
-     */
-    public function saveQuickStylesAction()
-    {
-        $controlId = $this->getRequest()->getParam('id');
-        $controlValue = $this->getRequest()->getParam('value');
-        try {
-            $themeContext = $this->_initContext();
-            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
-            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
-            $configuration = $configFactory->create(
-                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
-                $themeContext->getStagingTheme(),
-                $themeContext->getEditableTheme()->getParentTheme()
-            );
-            $configuration->saveData(array($controlId => $controlValue));
-            $response = array('success' => true);
-        } catch (CoreException $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        } catch (\Exception $e) {
-            $errorMessage = __(
-                'Something went wrong uploading the image.' .
-                ' Please check the file format and try again (JPEG, GIF, or PNG).'
-            );
-            $response = array('error' => true, 'message' => $errorMessage);
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-        );
-    }
-
     /**
      * Re-init system configuration
      *
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..8bde881268f1659afc1f5587a6cb26966c12e825
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/DeleteCustomFiles.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+class DeleteCustomFiles extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Delete custom file action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $removeJsFiles = (array)$this->getRequest()->getParam('js_removed_files');
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $editableTheme->getCustomization()->delete($removeJsFiles);
+            $this->_forward('jsList');
+        } catch (\Exception $e) {
+            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
new file mode 100644
index 0000000000000000000000000000000000000000..245b4125eac2f2d35f8ed6b72ae6d3296a6056bb
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/JsList.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+class JsList extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Ajax list of existing javascript files
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $customization = $editableTheme->getCustomization();
+            $customJsFiles = $customization->getFilesByType(\Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE);
+            $result = array('error' => false, 'files' => $customization->generateFileInfo($customJsFiles));
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
new file mode 100644
index 0000000000000000000000000000000000000000..9cad989301b403e07c2bf66163e6132d7b1d4f2c
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveQuickStyleImage.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class RemoveQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Remove quick style image
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $fileName = $this->getRequest()->getParam('file_name', false);
+        $elementName = $this->getRequest()->getParam('element', false);
+
+        /** @var $uploaderModel \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader */
+        $uploaderModel = $this->_objectManager->get(
+            'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader'
+        );
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $result = $uploaderModel->setTheme($editableTheme)->removeFile($fileName);
+
+            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
+            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
+
+            $configuration = $configFactory->create(
+                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
+                $editableTheme,
+                $themeContext->getEditableTheme()->getParentTheme()
+            );
+            $configuration->saveData(array($elementName => ''));
+
+            $response = array('error' => false, 'content' => $result);
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $errorMessage = __(
+                'Something went wrong uploading the image.' .
+                ' Please check the file format and try again (JPEG, GIF, or PNG).'
+            );
+            $response = array('error' => true, 'message' => $errorMessage);
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
new file mode 100644
index 0000000000000000000000000000000000000000..706a5f4aedffc736901dc08bb78a4826fcf55de3
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/RemoveStoreLogo.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class RemoveStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Remove store logo
+     *
+     * @return void
+     * @throws CoreException
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        try {
+            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
+            if (!$theme->load($themeId)->getId() || !$theme->isEditable()) {
+                throw new CoreException(__('The file can\'t be found or edited.'));
+            }
+
+            /** @var $customizationConfig \Magento\Theme\Model\Config\Customization */
+            $customizationConfig = $this->_objectManager->get('Magento\Theme\Model\Config\Customization');
+            $store = $this->_objectManager->get('Magento\Store\Model\Store')->load($storeId);
+
+            if (!$customizationConfig->isThemeAssignedToStore($theme, $store)) {
+                throw new CoreException(__('This theme is not assigned to a store view #%1.', $theme->getId()));
+            }
+
+            $this->_objectManager->get(
+                'Magento\Backend\Model\Config\Backend\Store'
+            )->setScope(
+                'stores'
+            )->setScopeId(
+                $store->getId()
+            )->setPath(
+                'design/header/logo_src'
+            )->setValue(
+                ''
+            )->save();
+
+            $this->_reinitSystemConfiguration();
+            $response = array('error' => false, 'content' => array());
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $errorMessage = __(
+                'Something went wrong uploading the image.' .
+                ' Please check the file format and try again (JPEG, GIF, or PNG).'
+            );
+            $response = array('error' => true, 'message' => $errorMessage);
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
new file mode 100644
index 0000000000000000000000000000000000000000..84a09ce08fd3d3e807447e245db6fc19a8f6392f
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/ReorderJs.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class ReorderJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Reorder js file
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $reorderJsFiles = (array)$this->getRequest()->getParam('js_order', array());
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $editableTheme->getCustomization()->reorder(
+                \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE,
+                $reorderJsFiles
+            );
+            $result = array('success' => true);
+        } catch (CoreException $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
new file mode 100644
index 0000000000000000000000000000000000000000..e841b3a7a063570343e0a48ef5283c63769fd355
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveCssContent.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class SaveCssContent extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Save custom css file
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customCssContent = (string)$this->getRequest()->getParam('custom_css_content', '');
+        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
+        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
+        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
+        $singleFile = $this->_objectManager->create(
+            'Magento\Theme\Model\Theme\SingleFile',
+            array('fileService' => $cssService)
+        );
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $customCss = $singleFile->update($editableTheme, $customCssContent);
+            $response = array(
+                'success' => true,
+                'filename' => $customCss->getFileName(),
+                'message' => __('You updated the %1 file.', $customCss->getFileName())
+            );
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('We can\'t save the custom css file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
new file mode 100644
index 0000000000000000000000000000000000000000..658c917ccc9a75bed0e6cc1bda63e718f4750e55
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveImageSizing.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class SaveImageSizing extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Save image sizes
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $imageSizing = $this->getRequest()->getParam('imagesizing');
+        /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
+        $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
+        /** @var $imageSizingValidator \Magento\DesignEditor\Model\Editor\Tools\ImageSizing\Validator */
+        $imageSizingValidator = $this->_objectManager->get(
+            'Magento\DesignEditor\Model\Editor\Tools\ImageSizing\Validator'
+        );
+        try {
+            $themeContext = $this->_initContext();
+            $configuration = $configFactory->create(
+                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_IMAGE_SIZING,
+                $themeContext->getStagingTheme(),
+                $themeContext->getEditableTheme()->getParentTheme()
+            );
+            $imageSizing = $imageSizingValidator->validate($configuration->getAllControlsData(), $imageSizing);
+            $configuration->saveData($imageSizing);
+            $result = array('success' => true, 'message' => __('We saved the image sizes.'));
+        } catch (CoreException $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => __('We can\'t save image sizes.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
new file mode 100644
index 0000000000000000000000000000000000000000..49c950917e04257844140c90d4adf7f3afb43b86
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/SaveQuickStyles.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class SaveQuickStyles extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Save quick styles data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $controlId = $this->getRequest()->getParam('id');
+        $controlValue = $this->getRequest()->getParam('value');
+        try {
+            $themeContext = $this->_initContext();
+            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
+            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
+            $configuration = $configFactory->create(
+                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
+                $themeContext->getStagingTheme(),
+                $themeContext->getEditableTheme()->getParentTheme()
+            );
+            $configuration->saveData(array($controlId => $controlValue));
+            $response = array('success' => true);
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $errorMessage = __(
+                'Something went wrong uploading the image.' .
+                ' Please check the file format and try again (JPEG, GIF, or PNG).'
+            );
+            $response = array('error' => true, 'message' => $errorMessage);
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb65ae6f4c75a615cdb5908ff99f8994aeb0370c
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/Upload.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class Upload extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Upload custom CSS action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
+        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
+        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
+        $singleFile = $this->_objectManager->create(
+            'Magento\Theme\Model\Theme\SingleFile',
+            array('fileService' => $cssService)
+        );
+        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
+        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $cssFileData = $serviceModel->uploadCssFile(
+                \Magento\DesignEditor\Block\Adminhtml\Editor\Tools\Code\Custom::FILE_ELEMENT_NAME
+            );
+            $singleFile->update($editableTheme, $cssFileData['content']);
+            $response = array(
+                'success' => true,
+                'message' => __('You updated the custom.css file.'),
+                'content' => $cssFileData['content']
+            );
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec6d9b094fd08197c98d43b75d6b1b381b6dfb71
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadJs.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class UploadJs extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Upload js file
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
+        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
+        /** @var $jsService \Magento\Framework\View\Design\Theme\Customization\File\Js */
+        $jsService = $this->_objectManager->create('Magento\Framework\View\Design\Theme\Customization\File\Js');
+        try {
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $jsFileData = $serviceModel->uploadJsFile('js_files_uploader');
+            $jsFile = $jsService->create();
+            $jsFile->setTheme($editableTheme);
+            $jsFile->setFileName($jsFileData['filename']);
+            $jsFile->setData('content', $jsFileData['content']);
+            $jsFile->save();
+            $this->_forward('jsList');
+            return;
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('We cannot upload the JS file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b79f50ff0f49cb2d70ef300680f7cc852724285
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadQuickStyleImage.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class UploadQuickStyleImage extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Upload quick style image
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $uploaderModel \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader */
+        $uploaderModel = $this->_objectManager->get(
+            'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\ImageUploader'
+        );
+        try {
+            /** @var $configFactory \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory */
+            $configFactory = $this->_objectManager->create('Magento\DesignEditor\Model\Editor\Tools\Controls\Factory');
+            $themeContext = $this->_initContext();
+            $editableTheme = $themeContext->getStagingTheme();
+            $keys = array_keys($this->getRequest()->getFiles());
+            $result = $uploaderModel->setTheme($editableTheme)->uploadFile($keys[0]);
+
+            $configuration = $configFactory->create(
+                \Magento\DesignEditor\Model\Editor\Tools\Controls\Factory::TYPE_QUICK_STYLES,
+                $editableTheme,
+                $themeContext->getEditableTheme()->getParentTheme()
+            );
+            $configuration->saveData(array($keys[0] => $result['css_path']));
+
+            $response = array('error' => false, 'content' => $result);
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $errorMessage = __(
+                'Something went wrong uploading the image.' .
+                ' Please check the file format and try again (JPEG, GIF, or PNG).'
+            );
+            $response = array('error' => true, 'message' => $errorMessage);
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
new file mode 100644
index 0000000000000000000000000000000000000000..fbce5ac2ae0fdd5be0a83867806550da3f45a29a
--- /dev/null
+++ b/app/code/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/Tools/UploadStoreLogo.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools;
+
+use Magento\Framework\Model\Exception as CoreException;
+
+class UploadStoreLogo extends \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Tools
+{
+    /**
+     * Upload store logo
+     *
+     * @return void
+     * @throws CoreException
+     */
+    public function execute()
+    {
+        $storeId = (int)$this->getRequest()->getParam('store_id');
+        $themeId = (int)$this->getRequest()->getParam('theme_id');
+        try {
+            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
+            if (!$theme->load($themeId)->getId() || !$theme->isEditable()) {
+                throw new CoreException(__('The file can\'t be found or edited.'));
+            }
+
+            /** @var $customizationConfig \Magento\Theme\Model\Config\Customization */
+            $customizationConfig = $this->_objectManager->get('Magento\Theme\Model\Config\Customization');
+            $store = $this->_objectManager->get('Magento\Store\Model\Store')->load($storeId);
+
+            if (!$customizationConfig->isThemeAssignedToStore($theme, $store)) {
+                throw new CoreException(__('This theme is not assigned to a store view #%1.', $theme->getId()));
+            }
+            /** @var $storeLogo \Magento\DesignEditor\Model\Editor\Tools\QuickStyles\LogoUploader */
+            $storeLogo = $this->_objectManager->get(
+                'Magento\DesignEditor\Model\Editor\Tools\QuickStyles\LogoUploader'
+            );
+            $storeLogo->setScope('stores')->setScopeId($store->getId())->setPath('design/header/logo_src')->save();
+
+            $this->_reinitSystemConfiguration();
+
+            $response = array('error' => false, 'content' => array('name' => basename($storeLogo->getValue())));
+        } catch (CoreException $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        } catch (\Exception $e) {
+            $errorMessage = __(
+                'Something went wrong uploading the image.' .
+                ' Please check the file format and try again (JPEG, GIF, or PNG).'
+            );
+            $response = array('error' => true, 'message' => $errorMessage);
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
+        );
+    }
+}
diff --git a/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php b/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
index f29b2c2f2cc62327dfbf83aa72450c5a3db8b660..21dcd9aa839602052135dbdf16a0647c92e09e4c 100644
--- a/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
+++ b/app/code/Magento/DesignEditor/Controller/Varien/Router/Standard.php
@@ -69,6 +69,7 @@ class Standard extends \Magento\Core\App\Router\Base
     protected $_session;
 
     /**
+     * @param \Magento\Framework\App\Router\ActionList $actionList
      * @param \Magento\Framework\App\ActionFactory $actionFactory
      * @param \Magento\Framework\App\DefaultPathInterface $defaultPath
      * @param \Magento\Framework\App\ResponseFactory $responseFactory
@@ -81,7 +82,6 @@ class Standard extends \Magento\Core\App\Router\Base
      * @param string $routerId
      * @param \Magento\Framework\Code\NameBuilder $nameBuilder
      * @param \Magento\Framework\App\RouterListInterface $routerList
-     * @param \Magento\Framework\ObjectManager $objectManager
      * @param \Magento\UrlRewrite\App\Request\RewriteService $urlRewriteService
      * @param \Magento\DesignEditor\Helper\Data $designEditorHelper
      * @param \Magento\DesignEditor\Model\State $designEditorState
@@ -90,6 +90,7 @@ class Standard extends \Magento\Core\App\Router\Base
      * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
+        \Magento\Framework\App\Router\ActionList $actionList,
         \Magento\Framework\App\ActionFactory $actionFactory,
         \Magento\Framework\App\DefaultPathInterface $defaultPath,
         \Magento\Framework\App\ResponseFactory $responseFactory,
@@ -102,13 +103,13 @@ class Standard extends \Magento\Core\App\Router\Base
         $routerId,
         \Magento\Framework\Code\NameBuilder $nameBuilder,
         \Magento\Framework\App\RouterListInterface $routerList,
-        \Magento\Framework\ObjectManager $objectManager,
         \Magento\UrlRewrite\App\Request\RewriteService $urlRewriteService,
         \Magento\DesignEditor\Helper\Data $designEditorHelper,
         \Magento\DesignEditor\Model\State $designEditorState,
         \Magento\Backend\Model\Auth\Session $session
     ) {
         parent::__construct(
+            $actionList,
             $actionFactory,
             $defaultPath,
             $responseFactory,
@@ -155,7 +156,7 @@ class Standard extends \Magento\Core\App\Router\Base
         // match routers
         $controller = null;
         $routers = $this->_getMatchedRouters();
-        /** @var $router \Magento\Framework\App\Router\AbstractRouter */
+        /** @var $router \Magento\Framework\App\RouterInterface */
         foreach ($routers as $router) {
             /** @var $controller \Magento\Framework\App\Action\AbstractAction */
             $controller = $router->match($request);
diff --git a/app/code/Magento/Directory/Controller/Adminhtml/Json.php b/app/code/Magento/Directory/Controller/Adminhtml/Json/CountryRegion.php
similarity index 88%
rename from app/code/Magento/Directory/Controller/Adminhtml/Json.php
rename to app/code/Magento/Directory/Controller/Adminhtml/Json/CountryRegion.php
index af8e1ea22051dd8d24283c191ae4745cb780f5aa..bef60ea2b105d5ca7c62dff8f12535230e3895e8 100644
--- a/app/code/Magento/Directory/Controller/Adminhtml/Json.php
+++ b/app/code/Magento/Directory/Controller/Adminhtml/Json/CountryRegion.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,22 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Directory\Controller\Adminhtml\Json;
 
-/**
- * Json controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Directory\Controller\Adminhtml;
-
-class Json extends \Magento\Backend\App\Action
+class CountryRegion extends \Magento\Backend\App\Action
 {
     /**
      * Return JSON-encoded array of country regions
      *
      * @return string
      */
-    public function countryRegionAction()
+    public function execute()
     {
         $arrRes = array();
 
diff --git a/app/code/Magento/Directory/Controller/Currency.php b/app/code/Magento/Directory/Controller/Currency/SwitchAction.php
similarity index 89%
rename from app/code/Magento/Directory/Controller/Currency.php
rename to app/code/Magento/Directory/Controller/Currency/SwitchAction.php
index 170447c34964d6429db7f97f8d7846fe61b8d3d6..c37f8e497c530bbb5f6200773616c34ca2355f6b 100644
--- a/app/code/Magento/Directory/Controller/Currency.php
+++ b/app/code/Magento/Directory/Controller/Currency/SwitchAction.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,18 +22,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Directory\Controller\Currency;
 
-/**
- * Currency controller
- */
-namespace Magento\Directory\Controller;
-
-class Currency extends \Magento\Framework\App\Action\Action
+class SwitchAction extends \Magento\Framework\App\Action\Action
 {
     /**
      * @return void
      */
-    public function switchAction()
+    public function execute()
     {
         /** @var \Magento\Store\Model\StoreManagerInterface $storeManager */
         $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php
index cc2f352164739c7a9be45ff1ef8e5962169cfe4a..d6f8c881d11851ccb4148d702ed983e94e5dd62a 100644
--- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File.php
@@ -65,59 +65,6 @@ class File extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Upload file controller action
-     *
-     * @return void
-     */
-    public function uploadAction()
-    {
-        $type = $this->getRequest()->getParam('type');
-        $tmpPath = '';
-        if ($type == 'samples') {
-            $tmpPath = $this->_sample->getBaseTmpPath();
-        } elseif ($type == 'links') {
-            $tmpPath = $this->_link->getBaseTmpPath();
-        } elseif ($type == 'link_samples') {
-            $tmpPath = $this->_link->getBaseSampleTmpPath();
-        }
-
-        try {
-            $uploader = $this->_objectManager->create('Magento\Core\Model\File\Uploader', array('fileId' => $type));
-
-            $result = $this->_fileHelper->uploadFromTmp($tmpPath, $uploader);
-
-            if (!$result) {
-                throw new \Exception('File can not be moved from temporary folder to the destination folder.');
-            }
-
-            /**
-             * Workaround for prototype 1.7 methods "isJSON", "evalJSON" on Windows OS
-             */
-            $result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
-            $result['path'] = str_replace('\\', '/', $result['path']);
-
-            if (isset($result['file'])) {
-                $relativePath = rtrim($tmpPath, '/') . '/' . ltrim($result['file'], '/');
-                $this->_objectManager->get('Magento\Core\Helper\File\Storage\Database')->saveFile($relativePath);
-            }
-
-            $result['cookie'] = array(
-                'name' => $this->_getSession()->getName(),
-                'value' => $this->_getSession()->getSessionId(),
-                'lifetime' => $this->_getSession()->getCookieLifetime(),
-                'path' => $this->_getSession()->getCookiePath(),
-                'domain' => $this->_getSession()->getCookieDomain()
-            );
-        } catch (\Exception $e) {
-            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
-        }
-
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
     /**
      * Check admin permissions for this controller
      *
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..a74770fd62720b6b68ea32348f7451fb69b1ca93
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/File/Upload.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\File;
+
+class Upload extends \Magento\Downloadable\Controller\Adminhtml\Downloadable\File
+{
+    /**
+     * Upload file controller action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $type = $this->getRequest()->getParam('type');
+        $tmpPath = '';
+        if ($type == 'samples') {
+            $tmpPath = $this->_sample->getBaseTmpPath();
+        } elseif ($type == 'links') {
+            $tmpPath = $this->_link->getBaseTmpPath();
+        } elseif ($type == 'link_samples') {
+            $tmpPath = $this->_link->getBaseSampleTmpPath();
+        }
+
+        try {
+            $uploader = $this->_objectManager->create('Magento\Core\Model\File\Uploader', array('fileId' => $type));
+
+            $result = $this->_fileHelper->uploadFromTmp($tmpPath, $uploader);
+
+            if (!$result) {
+                throw new \Exception('File can not be moved from temporary folder to the destination folder.');
+            }
+
+            /**
+             * Workaround for prototype 1.7 methods "isJSON", "evalJSON" on Windows OS
+             */
+            $result['tmp_name'] = str_replace('\\', '/', $result['tmp_name']);
+            $result['path'] = str_replace('\\', '/', $result['path']);
+
+            if (isset($result['file'])) {
+                $relativePath = rtrim($tmpPath, '/') . '/' . ltrim($result['file'], '/');
+                $this->_objectManager->get('Magento\Core\Helper\File\Storage\Database')->saveFile($relativePath);
+            }
+
+            $result['cookie'] = array(
+                'name' => $this->_getSession()->getName(),
+                'value' => $this->_getSession()->getSessionId(),
+                'lifetime' => $this->_getSession()->getCookieLifetime(),
+                'path' => $this->_getSession()->getCookiePath(),
+                'domain' => $this->_getSession()->getCookieDomain()
+            );
+        } catch (\Exception $e) {
+            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
+        }
+
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AddAttributeToTemplate.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AddAttributeToTemplate.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b104c65836623357bc6b6964ad22dbbda0aa4e4
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AddAttributeToTemplate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class AddAttributeToTemplate extends \Magento\Catalog\Controller\Adminhtml\Product\AddAttributeToTemplate
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsPriceGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsPriceGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..32331d348ed7553f26b4a2c8b66c6935174b2c77
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsPriceGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class AlertsPriceGrid extends \Magento\Catalog\Controller\Adminhtml\Product\AlertsPriceGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsStockGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsStockGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d11d2ad8b56167378837f7e5520c83417f64012
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/AlertsStockGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class AlertsStockGrid extends \Magento\Catalog\Controller\Adminhtml\Product\AlertsStockGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Categories.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Categories.php
new file mode 100644
index 0000000000000000000000000000000000000000..fe800693dae338b6e649c276ca992dbcdf991749
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Categories.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Categories extends \Magento\Catalog\Controller\Adminhtml\Product\Categories
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Crosssell.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Crosssell.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5de46df0bd990b9a74be4b2d1a01196e4a910e6
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Crosssell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Crosssell extends \Magento\Catalog\Controller\Adminhtml\Product\Crosssell
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CrosssellGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CrosssellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..682b03fd9bcc13c593cd9ac692203bea05d1eed0
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CrosssellGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class CrosssellGrid extends \Magento\Catalog\Controller\Adminhtml\Product\CrosssellGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CustomOptions.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CustomOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..05e8b2fa12f203086148b653ee1e606af6f77a50
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/CustomOptions.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class CustomOptions extends \Magento\Catalog\Controller\Adminhtml\Product\CustomOptions
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Duplicate.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Duplicate.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5bb4453a00a78a813156685a70499dfee771f7a
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Duplicate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Duplicate extends \Magento\Catalog\Controller\Adminhtml\Product\Duplicate
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Edit.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd888c04bf435e2a4e02a7b343e4a72e7f23baa5
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Edit.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Edit extends \Magento\Catalog\Controller\Adminhtml\Product\Edit
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Form.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fac1d15484adaf13fb2e3e947d0a3b4aad117bd
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Form.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Form extends \Magento\Catalog\Controller\Adminhtml\Product\Edit
+{
+    /**
+     * Load downloadable tab fieldsets
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initProduct();
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Downloadable\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable',
+                'admin.product.downloadable.information'
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Grid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..3bf7a7e355c7126f9296a633ab90104031f16b13
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Grid extends \Magento\Catalog\Controller\Adminhtml\Product\Grid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/GridOnly.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/GridOnly.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b8cb93b8234ede2bfcb0efa676b4b33687c86be
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/GridOnly.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class GridOnly extends \Magento\Catalog\Controller\Adminhtml\Product\GridOnly
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Index.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b08669731100566c5850ce65a0a82f1f8a200835
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Index extends \Magento\Catalog\Controller\Adminhtml\Product\Index
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Link.php
similarity index 86%
rename from app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit.php
rename to app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Link.php
index 381fbf736304e0c3da1f600f1b58ddeefbb9a409..468b2245c2f329060c3abd2d25a2ddcf316dcfbe 100644
--- a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit.php
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Link.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,31 +22,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product;
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
 
 use Magento\Downloadable\Helper\Download as DownloadHelper;
 
-/**
- * Adminhtml downloadable product edit
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
+class Link extends \Magento\Catalog\Controller\Adminhtml\Product\Edit
 {
     /**
-     * Load downloadable tab fieldsets
-     *
-     * @return void
+     * @return \Magento\Downloadable\Model\Link
      */
-    public function formAction()
+    protected function _createLink()
     {
-        $this->_initProduct();
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Downloadable\Block\Adminhtml\Catalog\Product\Edit\Tab\Downloadable',
-                'admin.product.downloadable.information'
-            )->toHtml()
-        );
+        return $this->_objectManager->create('Magento\Downloadable\Model\Link');
+    }
+
+    /**
+     * @return \Magento\Downloadable\Model\Link
+     */
+    protected function _getLink()
+    {
+        return $this->_objectManager->get('Magento\Downloadable\Model\Link');
     }
 
     /**
@@ -99,7 +95,7 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
      *
      * @return void
      */
-    public function linkAction()
+    public function execute()
     {
         $linkId = $this->getRequest()->getParam('id', 0);
         /** @var \Magento\Downloadable\Model\Link $link */
@@ -127,20 +123,4 @@ class Edit extends \Magento\Catalog\Controller\Adminhtml\Product
         }
         exit(0);
     }
-
-    /**
-     * @return \Magento\Downloadable\Model\Link
-     */
-    protected function _getLink()
-    {
-        return $this->_objectManager->get('Magento\Downloadable\Model\Link');
-    }
-
-    /**
-     * @return \Magento\Downloadable\Model\Link
-     */
-    protected function _createLink()
-    {
-        return $this->_objectManager->create('Magento\Downloadable\Model\Link');
-    }
 }
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassDelete.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..72cc50adc913c62671f6a7e2f3be3ecd52c5c5b8
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassDelete.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class MassDelete extends \Magento\Catalog\Controller\Adminhtml\Product\MassDelete
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassStatus.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..e5781a568f43f77a51f7a3fb31d714cab4a3e42b
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/MassStatus.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class MassStatus extends \Magento\Catalog\Controller\Adminhtml\Product\MassStatus
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/NewAction.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb088948bb5f45aeba25a1673dc446ebfa1a4c93
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/NewAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class NewAction extends \Magento\Catalog\Controller\Adminhtml\Product\NewAction
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Options.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Options.php
new file mode 100644
index 0000000000000000000000000000000000000000..696c617bdd20da28de1932174cc484ac3f19afd8
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Options.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Options extends \Magento\Catalog\Controller\Adminhtml\Product\Options
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/OptionsImportGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/OptionsImportGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..0377f121a08152bda88995c4a906ebd7fd3dc4a3
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/OptionsImportGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class OptionsImportGrid extends \Magento\Catalog\Controller\Adminhtml\Product\OptionsImportGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Related.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Related.php
new file mode 100644
index 0000000000000000000000000000000000000000..b09a6972d0028a716fd3965be569da675a942131
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Related.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Related extends \Magento\Catalog\Controller\Adminhtml\Product\Related
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/RelatedGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/RelatedGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..d71dc9a2a0bea3f1b01a5f7a3dcf666e17b2ef9f
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/RelatedGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class RelatedGrid extends \Magento\Catalog\Controller\Adminhtml\Product\RelatedGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Save.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..a21e16e84ee516e4e4699084b3d61b21d7c2a5c6
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Save.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Save extends \Magento\Catalog\Controller\Adminhtml\Product\Save
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/ShowUpdateResult.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..75d583f5d80b94197583c32f80b7854023bca356
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/ShowUpdateResult.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class ShowUpdateResult extends \Magento\Catalog\Controller\Adminhtml\Product\ShowUpdateResult
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestAttributes.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestAttributes.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c72ba1e26049aa6fbc2940e5b3f0c32f550d509
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestAttributes.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class SuggestAttributes extends \Magento\Catalog\Controller\Adminhtml\Product\SuggestAttributes
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestProductTemplates.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestProductTemplates.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c2e7bb72141584406f75554fee20e01a00da5b0
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/SuggestProductTemplates.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class SuggestProductTemplates extends \Magento\Catalog\Controller\Adminhtml\Product\SuggestProductTemplates
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Upsell.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Upsell.php
new file mode 100644
index 0000000000000000000000000000000000000000..9a7694fbf280a1edca3227ed6f5cfa7f59998461
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Upsell.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Upsell extends \Magento\Catalog\Controller\Adminhtml\Product\Upsell
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/UpsellGrid.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/UpsellGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba81bc57be0357b6e9a7837204a121c9df47b652
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/UpsellGrid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class UpsellGrid extends \Magento\Catalog\Controller\Adminhtml\Product\UpsellGrid
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Validate.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..47f8379674b2b1de3bc022de56801457c0e2235a
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Validate.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Validate extends \Magento\Catalog\Controller\Adminhtml\Product\Validate
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Wysiwyg.php b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Wysiwyg.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9a920c257e112c610d3e8cec594849d543da5dd
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Adminhtml/Downloadable/Product/Edit/Wysiwyg.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Adminhtml\Downloadable\Product\Edit;
+
+class Wysiwyg extends \Magento\Catalog\Controller\Adminhtml\Product\Wysiwyg
+{
+}
diff --git a/app/code/Magento/Downloadable/Controller/Customer.php b/app/code/Magento/Downloadable/Controller/Customer/Products.php
similarity index 91%
rename from app/code/Magento/Downloadable/Controller/Customer.php
rename to app/code/Magento/Downloadable/Controller/Customer/Products.php
index 0078c5de62b60af650bd091344cfbfe4ae71610c..b2db83e6667245768b7e828de1a8f0cdf30762ea 100644
--- a/app/code/Magento/Downloadable/Controller/Customer.php
+++ b/app/code/Magento/Downloadable/Controller/Customer/Products.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,16 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Downloadable\Controller;
+namespace Magento\Downloadable\Controller\Customer;
 
 use Magento\Framework\App\RequestInterface;
 
-/**
- * Customer account controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Customer extends \Magento\Framework\App\Action\Action
+class Products extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Customer\Model\Session
@@ -68,7 +64,7 @@ class Customer extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function productsAction()
+    public function execute()
     {
         $this->_view->loadLayout();
         $this->_view->getLayout()->initMessages();
diff --git a/app/code/Magento/Downloadable/Controller/Download.php b/app/code/Magento/Downloadable/Controller/Download.php
index df34d4b792a4d66d735af7cbd9950538f14db77e..2b3e841f46be3dc74529559f75df243304c94f38 100644
--- a/app/code/Magento/Downloadable/Controller/Download.php
+++ b/app/code/Magento/Downloadable/Controller/Download.php
@@ -23,9 +23,7 @@
  */
 namespace Magento\Downloadable\Controller;
 
-use Magento\Framework\App\ResponseInterface;
 use Magento\Downloadable\Helper\Download as DownloadHelper;
-use Magento\Downloadable\Model\Link\Purchased\Item as PurchasedLink;
 
 /**
  * Download controller
@@ -34,25 +32,6 @@ use Magento\Downloadable\Model\Link\Purchased\Item as PurchasedLink;
  */
 class Download extends \Magento\Framework\App\Action\Action
 {
-    /**
-     * Return core session object
-     *
-     * @return \Magento\Framework\Session\Generic
-     */
-    protected function _getSession()
-    {
-        return $this->_objectManager->get('Magento\Framework\Session\Generic');
-    }
-
-    /**
-     * Return customer session object
-     *
-     * @return \Magento\Customer\Model\Session
-     */
-    protected function _getCustomerSession()
-    {
-        return $this->_objectManager->get('Magento\Customer\Model\Session');
-    }
 
     /**
      * Prepare response to output resource contents
@@ -100,183 +79,6 @@ class Download extends \Magento\Framework\App\Action\Action
         $helper->output();
     }
 
-    /**
-     * Download sample action
-     *
-     * @return ResponseInterface
-     */
-    public function sampleAction()
-    {
-        $sampleId = $this->getRequest()->getParam('sample_id', 0);
-        /** @var \Magento\Downloadable\Model\Sample $sample */
-        $sample = $this->_objectManager->create('Magento\Downloadable\Model\Sample')->load($sampleId);
-        if ($sample->getId()) {
-            $resource = '';
-            $resourceType = '';
-            if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
-                $resource = $sample->getSampleUrl();
-                $resourceType = DownloadHelper::LINK_TYPE_URL;
-            } elseif ($sample->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
-                /** @var \Magento\Downloadable\Helper\File $helper */
-                $helper = $this->_objectManager->get('Magento\Downloadable\Helper\File');
-                $resource = $helper->getFilePath($sample->getBasePath(), $sample->getSampleFile());
-                $resourceType = DownloadHelper::LINK_TYPE_FILE;
-            }
-            try {
-                $this->_processDownload($resource, $resourceType);
-                exit(0);
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('Sorry, there was an error getting requested content. Please contact the store owner.')
-                );
-            }
-        }
-        return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Download link's sample action
-     *
-     * @return ResponseInterface
-     */
-    public function linkSampleAction()
-    {
-        $linkId = $this->getRequest()->getParam('link_id', 0);
-        /** @var \Magento\Downloadable\Model\Link $link */
-        $link = $this->_objectManager->create('Magento\Downloadable\Model\Link')->load($linkId);
-        if ($link->getId()) {
-            $resource = '';
-            $resourceType = '';
-            if ($link->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
-                $resource = $link->getSampleUrl();
-                $resourceType = DownloadHelper::LINK_TYPE_URL;
-            } elseif ($link->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
-                $resource = $this->_objectManager->get(
-                    'Magento\Downloadable\Helper\File'
-                )->getFilePath(
-                    $this->_getLink()->getBaseSamplePath(),
-                    $link->getSampleFile()
-                );
-                $resourceType = DownloadHelper::LINK_TYPE_FILE;
-            }
-            try {
-                $this->_processDownload($resource, $resourceType);
-                exit(0);
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('Sorry, there was an error getting requested content. Please contact the store owner.')
-                );
-            }
-        }
-        return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Download link action
-     *
-     * @return void|ResponseInterface
-     */
-    public function linkAction()
-    {
-        $session = $this->_getCustomerSession();
-
-        $id = $this->getRequest()->getParam('id', 0);
-        /** @var PurchasedLink $linkPurchasedItem */
-        $linkPurchasedItem = $this->_objectManager->create(
-            'Magento\Downloadable\Model\Link\Purchased\Item'
-        )->load(
-            $id,
-            'link_hash'
-        );
-        if (!$linkPurchasedItem->getId()) {
-            $this->messageManager->addNotice(__("We can't find the link you requested."));
-            return $this->_redirect('*/customer/products');
-        }
-        if (!$this->_objectManager->get('Magento\Downloadable\Helper\Data')->getIsShareable($linkPurchasedItem)) {
-            $customerId = $session->getCustomerId();
-            if (!$customerId) {
-                /** @var \Magento\Catalog\Model\Product $product */
-                $product = $this->_objectManager->create(
-                    'Magento\Catalog\Model\Product'
-                )->load(
-                    $linkPurchasedItem->getProductId()
-                );
-                if ($product->getId()) {
-                    $notice = __(
-                        'Please log in to download your product or purchase <a href="%1">%2</a>.',
-                        $product->getProductUrl(),
-                        $product->getName()
-                    );
-                } else {
-                    $notice = __('Please log in to download your product.');
-                }
-                $this->messageManager->addNotice($notice);
-                $session->authenticate($this);
-                $session->setBeforeAuthUrl(
-                    $this->_objectManager->create(
-                        'Magento\Framework\UrlInterface'
-                    )->getUrl(
-                        'downloadable/customer/products/',
-                        array('_secure' => true)
-                    )
-                );
-                return;
-            }
-            /** @var \Magento\Downloadable\Model\Link\Purchased $linkPurchased */
-            $linkPurchased = $this->_objectManager->create(
-                'Magento\Downloadable\Model\Link\Purchased'
-            )->load(
-                $linkPurchasedItem->getPurchasedId()
-            );
-            if ($linkPurchased->getCustomerId() != $customerId) {
-                $this->messageManager->addNotice(__("We can't find the link you requested."));
-                return $this->_redirect('*/customer/products');
-            }
-        }
-        $downloadsLeft = $linkPurchasedItem->getNumberOfDownloadsBought() -
-            $linkPurchasedItem->getNumberOfDownloadsUsed();
-
-        $status = $linkPurchasedItem->getStatus();
-        if ($status == PurchasedLink::LINK_STATUS_AVAILABLE && ($downloadsLeft ||
-            $linkPurchasedItem->getNumberOfDownloadsBought() == 0)
-        ) {
-            $resource = '';
-            $resourceType = '';
-            if ($linkPurchasedItem->getLinkType() == DownloadHelper::LINK_TYPE_URL) {
-                $resource = $linkPurchasedItem->getLinkUrl();
-                $resourceType = DownloadHelper::LINK_TYPE_URL;
-            } elseif ($linkPurchasedItem->getLinkType() == DownloadHelper::LINK_TYPE_FILE) {
-                $resource = $this->_objectManager->get(
-                    'Magento\Downloadable\Helper\File'
-                )->getFilePath(
-                    $this->_getLink()->getBasePath(),
-                    $linkPurchasedItem->getLinkFile()
-                );
-                $resourceType = DownloadHelper::LINK_TYPE_FILE;
-            }
-            try {
-                $this->_processDownload($resource, $resourceType);
-                $linkPurchasedItem->setNumberOfDownloadsUsed($linkPurchasedItem->getNumberOfDownloadsUsed() + 1);
-
-                if ($linkPurchasedItem->getNumberOfDownloadsBought() != 0 && !($downloadsLeft - 1)) {
-                    $linkPurchasedItem->setStatus(PurchasedLink::LINK_STATUS_EXPIRED);
-                }
-                $linkPurchasedItem->save();
-                exit(0);
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Something went wrong while getting the requested content.'));
-            }
-        } elseif ($status == PurchasedLink::LINK_STATUS_EXPIRED) {
-            $this->messageManager->addNotice(__('The link has expired.'));
-        } elseif ($status == PurchasedLink::LINK_STATUS_PENDING || $status == PurchasedLink::LINK_STATUS_PAYMENT_REVIEW
-        ) {
-            $this->messageManager->addNotice(__('The link is not available.'));
-        } else {
-            $this->messageManager->addError(__('Something went wrong while getting the requested content.'));
-        }
-        return $this->_redirect('*/customer/products');
-    }
-
     /**
      * Get link model
      *
diff --git a/app/code/Magento/Downloadable/Controller/Download/Link.php b/app/code/Magento/Downloadable/Controller/Download/Link.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a5e21c3d6b566d4a2da06392e76190e11671c65
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Download/Link.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Download;
+
+use Magento\Framework\App\ResponseInterface;
+use Magento\Downloadable\Helper\Download as DownloadHelper;
+use Magento\Downloadable\Model\Link\Purchased\Item as PurchasedLink;
+
+class Link extends \Magento\Downloadable\Controller\Download
+{
+    /**
+     * Return customer session object
+     *
+     * @return \Magento\Customer\Model\Session
+     */
+    protected function _getCustomerSession()
+    {
+        return $this->_objectManager->get('Magento\Customer\Model\Session');
+    }
+
+    /**
+     * Download link action
+     *
+     * @return void|ResponseInterface
+     */
+    public function execute()
+    {
+        $session = $this->_getCustomerSession();
+
+        $id = $this->getRequest()->getParam('id', 0);
+        /** @var PurchasedLink $linkPurchasedItem */
+        $linkPurchasedItem = $this->_objectManager->create(
+            'Magento\Downloadable\Model\Link\Purchased\Item'
+        )->load(
+            $id,
+            'link_hash'
+        );
+        if (!$linkPurchasedItem->getId()) {
+            $this->messageManager->addNotice(__("We can't find the link you requested."));
+            return $this->_redirect('*/customer/products');
+        }
+        if (!$this->_objectManager->get('Magento\Downloadable\Helper\Data')->getIsShareable($linkPurchasedItem)) {
+            $customerId = $session->getCustomerId();
+            if (!$customerId) {
+                /** @var \Magento\Catalog\Model\Product $product */
+                $product = $this->_objectManager->create(
+                    'Magento\Catalog\Model\Product'
+                )->load(
+                    $linkPurchasedItem->getProductId()
+                );
+                if ($product->getId()) {
+                    $notice = __(
+                        'Please log in to download your product or purchase <a href="%1">%2</a>.',
+                        $product->getProductUrl(),
+                        $product->getName()
+                    );
+                } else {
+                    $notice = __('Please log in to download your product.');
+                }
+                $this->messageManager->addNotice($notice);
+                $session->authenticate($this);
+                $session->setBeforeAuthUrl(
+                    $this->_objectManager->create(
+                        'Magento\Framework\UrlInterface'
+                    )->getUrl(
+                        'downloadable/customer/products/',
+                        array('_secure' => true)
+                    )
+                );
+                return;
+            }
+            /** @var \Magento\Downloadable\Model\Link\Purchased $linkPurchased */
+            $linkPurchased = $this->_objectManager->create(
+                'Magento\Downloadable\Model\Link\Purchased'
+            )->load(
+                $linkPurchasedItem->getPurchasedId()
+            );
+            if ($linkPurchased->getCustomerId() != $customerId) {
+                $this->messageManager->addNotice(__("We can't find the link you requested."));
+                return $this->_redirect('*/customer/products');
+            }
+        }
+        $downloadsLeft = $linkPurchasedItem->getNumberOfDownloadsBought() -
+            $linkPurchasedItem->getNumberOfDownloadsUsed();
+
+        $status = $linkPurchasedItem->getStatus();
+        if ($status == PurchasedLink::LINK_STATUS_AVAILABLE && ($downloadsLeft ||
+            $linkPurchasedItem->getNumberOfDownloadsBought() == 0)
+        ) {
+            $resource = '';
+            $resourceType = '';
+            if ($linkPurchasedItem->getLinkType() == DownloadHelper::LINK_TYPE_URL) {
+                $resource = $linkPurchasedItem->getLinkUrl();
+                $resourceType = DownloadHelper::LINK_TYPE_URL;
+            } elseif ($linkPurchasedItem->getLinkType() == DownloadHelper::LINK_TYPE_FILE) {
+                $resource = $this->_objectManager->get(
+                    'Magento\Downloadable\Helper\File'
+                )->getFilePath(
+                    $this->_getLink()->getBasePath(),
+                    $linkPurchasedItem->getLinkFile()
+                );
+                $resourceType = DownloadHelper::LINK_TYPE_FILE;
+            }
+            try {
+                $this->_processDownload($resource, $resourceType);
+                $linkPurchasedItem->setNumberOfDownloadsUsed($linkPurchasedItem->getNumberOfDownloadsUsed() + 1);
+
+                if ($linkPurchasedItem->getNumberOfDownloadsBought() != 0 && !($downloadsLeft - 1)) {
+                    $linkPurchasedItem->setStatus(PurchasedLink::LINK_STATUS_EXPIRED);
+                }
+                $linkPurchasedItem->save();
+                exit(0);
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong while getting the requested content.'));
+            }
+        } elseif ($status == PurchasedLink::LINK_STATUS_EXPIRED) {
+            $this->messageManager->addNotice(__('The link has expired.'));
+        } elseif ($status == PurchasedLink::LINK_STATUS_PENDING || $status == PurchasedLink::LINK_STATUS_PAYMENT_REVIEW
+        ) {
+            $this->messageManager->addNotice(__('The link is not available.'));
+        } else {
+            $this->messageManager->addError(__('Something went wrong while getting the requested content.'));
+        }
+        return $this->_redirect('*/customer/products');
+    }
+}
diff --git a/app/code/Magento/Downloadable/Controller/Download/LinkSample.php b/app/code/Magento/Downloadable/Controller/Download/LinkSample.php
new file mode 100644
index 0000000000000000000000000000000000000000..a748e3e65d9f803a20dee42a246cf4f75156af7f
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Download/LinkSample.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Download;
+
+use Magento\Framework\App\ResponseInterface;
+use Magento\Downloadable\Helper\Download as DownloadHelper;
+
+class LinkSample extends \Magento\Downloadable\Controller\Download
+{
+    /**
+     * Download link's sample action
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $linkId = $this->getRequest()->getParam('link_id', 0);
+        /** @var \Magento\Downloadable\Model\Link $link */
+        $link = $this->_objectManager->create('Magento\Downloadable\Model\Link')->load($linkId);
+        if ($link->getId()) {
+            $resource = '';
+            $resourceType = '';
+            if ($link->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
+                $resource = $link->getSampleUrl();
+                $resourceType = DownloadHelper::LINK_TYPE_URL;
+            } elseif ($link->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
+                $resource = $this->_objectManager->get(
+                    'Magento\Downloadable\Helper\File'
+                )->getFilePath(
+                    $this->_getLink()->getBaseSamplePath(),
+                    $link->getSampleFile()
+                );
+                $resourceType = DownloadHelper::LINK_TYPE_FILE;
+            }
+            try {
+                $this->_processDownload($resource, $resourceType);
+                exit(0);
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('Sorry, there was an error getting requested content. Please contact the store owner.')
+                );
+            }
+        }
+        return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Downloadable/Controller/Download/Sample.php b/app/code/Magento/Downloadable/Controller/Download/Sample.php
new file mode 100644
index 0000000000000000000000000000000000000000..287ea27e46d29f0b28e7a6882a14c945df374acd
--- /dev/null
+++ b/app/code/Magento/Downloadable/Controller/Download/Sample.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Downloadable\Controller\Download;
+
+use Magento\Framework\App\ResponseInterface;
+use Magento\Downloadable\Helper\Download as DownloadHelper;
+
+class Sample extends \Magento\Downloadable\Controller\Download
+{
+    /**
+     * Download sample action
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $sampleId = $this->getRequest()->getParam('sample_id', 0);
+        /** @var \Magento\Downloadable\Model\Sample $sample */
+        $sample = $this->_objectManager->create('Magento\Downloadable\Model\Sample')->load($sampleId);
+        if ($sample->getId()) {
+            $resource = '';
+            $resourceType = '';
+            if ($sample->getSampleType() == DownloadHelper::LINK_TYPE_URL) {
+                $resource = $sample->getSampleUrl();
+                $resourceType = DownloadHelper::LINK_TYPE_URL;
+            } elseif ($sample->getSampleType() == DownloadHelper::LINK_TYPE_FILE) {
+                /** @var \Magento\Downloadable\Helper\File $helper */
+                $helper = $this->_objectManager->get('Magento\Downloadable\Helper\File');
+                $resource = $helper->getFilePath($sample->getBasePath(), $sample->getSampleFile());
+                $resourceType = DownloadHelper::LINK_TYPE_FILE;
+            }
+            try {
+                $this->_processDownload($resource, $resourceType);
+                exit(0);
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('Sorry, there was an error getting requested content. Please contact the store owner.')
+                );
+            }
+        }
+        return $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Email/Block/Adminhtml/Template.php b/app/code/Magento/Email/Block/Adminhtml/Template.php
index 55689e365b0e98f1b276083bf30ba07bfc0d60e5..20296b1826c821da8f2f27ccb397a9e57b3352e2 100644
--- a/app/code/Magento/Email/Block/Adminhtml/Template.php
+++ b/app/code/Magento/Email/Block/Adminhtml/Template.php
@@ -29,7 +29,7 @@
  */
 namespace Magento\Email\Block\Adminhtml;
 
-class Template extends \Magento\Backend\Block\Template
+class Template extends \Magento\Backend\Block\Template implements \Magento\Backend\Block\Widget\ContainerInterface
 {
     /**
      * Template list
@@ -38,6 +38,42 @@ class Template extends \Magento\Backend\Block\Template
      */
     protected $_template = 'template/list.phtml';
 
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    protected $toolbar;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @param \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList,
+        \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar,
+        array $data = array()
+    ) {
+        $this->buttonList = $buttonList;
+        $this->toolbar = $toolbar;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function updateButton($buttonId, $key, $data)
+    {
+        $this->buttonList->update($buttonId, $key, $data);
+        return $this;
+    }
+
     /**
      * Create add button and grid blocks
      *
@@ -45,16 +81,15 @@ class Template extends \Magento\Backend\Block\Template
      */
     protected function _prepareLayout()
     {
-        $this->getToolbar()->addChild(
-            'add_button',
-            'Magento\Backend\Block\Widget\Button',
+        $this->buttonList->add(
+            'add',
             array(
                 'label' => __('Add New Template'),
                 'onclick' => "window.location='" . $this->getCreateUrl() . "'",
                 'class' => 'add primary add-template'
             )
         );
-
+        $this->toolbar->pushButtons($this, $this->buttonList);
         return parent::_prepareLayout();
     }
 
@@ -68,6 +103,15 @@ class Template extends \Magento\Backend\Block\Template
         return $this->getUrl('adminhtml/*/new');
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    {
+        $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
+        return $this;
+    }
+
     /**
      * Get transactional emails page header text
      *
@@ -78,6 +122,15 @@ class Template extends \Magento\Backend\Block\Template
         return __('Transactional Emails');
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function removeButton($buttonId)
+    {
+        $this->buttonList->remove($buttonId);
+        return $this;
+    }
+
     /**
      * Get Add New Template button html
      *
@@ -85,6 +138,21 @@ class Template extends \Magento\Backend\Block\Template
      */
     protected function getAddButtonHtml()
     {
-        return $this->getChildHtml('add_button');
+        $out = '';
+        foreach ($this->buttonList->getItems() as $buttons) {
+            /** @var \Magento\Backend\Block\Widget\Button\Item $item */
+            foreach ($buttons as $item) {
+                $out .= $this->getChildHtml($item->getButtonKey());
+            }
+        }
+        return $out;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function canRender(\Magento\Backend\Block\Widget\Button\Item $item)
+    {
+        return !$item->isDeleted();
     }
 }
diff --git a/app/code/Magento/Email/Block/Adminhtml/Template/Edit.php b/app/code/Magento/Email/Block/Adminhtml/Template/Edit.php
index bff42df3615d05c1e4bfd55e454101dddbe7a6d0..50d06bb8848fc8e907b992a73efab337f6e4d7a1 100644
--- a/app/code/Magento/Email/Block/Adminhtml/Template/Edit.php
+++ b/app/code/Magento/Email/Block/Adminhtml/Template/Edit.php
@@ -29,7 +29,7 @@ namespace Magento\Email\Block\Adminhtml\Template;
  * @author      Magento Core Team <core@magentocommerce.com>
  * @method array getTemplateOptions()
  */
-class Edit extends \Magento\Backend\Block\Widget
+class Edit extends \Magento\Backend\Block\Widget implements \Magento\Backend\Block\Widget\ContainerInterface
 {
     /**
      * @var \Magento\Framework\Registry
@@ -68,6 +68,16 @@ class Edit extends \Magento\Backend\Block\Widget
      */
     protected $_coreHelper;
 
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    protected $toolbar;
+
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
@@ -76,7 +86,11 @@ class Edit extends \Magento\Backend\Block\Widget
      * @param \Magento\Backend\Model\Config\Structure $configStructure
      * @param \Magento\Email\Model\Template\Config $emailConfig
      * @param \Magento\Core\Helper\Data $coreHelper
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @param \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar
      * @param array $data
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
@@ -86,6 +100,8 @@ class Edit extends \Magento\Backend\Block\Widget
         \Magento\Backend\Model\Config\Structure $configStructure,
         \Magento\Email\Model\Template\Config $emailConfig,
         \Magento\Core\Helper\Data $coreHelper,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList,
+        \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar,
         array $data = array()
     ) {
         $this->_coreHelper = $coreHelper;
@@ -94,9 +110,37 @@ class Edit extends \Magento\Backend\Block\Widget
         $this->_menuConfig = $menuConfig;
         $this->_configStructure = $configStructure;
         $this->_emailConfig = $emailConfig;
+        $this->buttonList = $buttonList;
+        $this->toolbar = $toolbar;
         parent::__construct($context, $data);
     }
 
+    /**
+     *{@inheritdoc}
+     */
+    public function updateButton($buttonId, $key, $data)
+    {
+        $this->buttonList->update($buttonId, $key, $data);
+        return $this;
+    }
+
+    /**
+     *{@inheritdoc}
+     */
+    public function canRender(\Magento\Backend\Block\Widget\Button\Item $item)
+    {
+        return !$item->isDeleted();
+    }
+
+    /**
+     *{@inheritdoc}
+     */
+    public function removeButton($buttonId)
+    {
+        $this->buttonList->remove($buttonId);
+        return $this;
+    }
+
     /**
      * Prepare layout
      *
@@ -105,104 +149,86 @@ class Edit extends \Magento\Backend\Block\Widget
      */
     protected function _prepareLayout()
     {
-        $this->getToolbar()->setChild(
-            'back_button',
-            $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Widget\Button'
-            )->setData(
-                array(
-                    'label' => __('Back'),
-                    'onclick' => "window.location.href = '" . $this->getUrl('adminhtml/*') . "'",
-                    'class' => 'back'
-                )
+        $this->buttonList->add(
+            'back',
+            array(
+                'label' => __('Back'),
+                'onclick' => "window.location.href = '" . $this->getUrl('adminhtml/*') . "'",
+                'class' => 'back'
             )
         );
-        $this->getToolbar()->setChild(
-            'reset_button',
-            $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Widget\Button'
-            )->setData(
-                array('label' => __('Reset'), 'onclick' => 'window.location.href = window.location.href')
-            )
+        $this->buttonList->add(
+            'reset',
+            array('label' => __('Reset'), 'onclick' => 'window.location.href = window.location.href')
         );
+
         if ($this->getEditMode()) {
-            $this->getToolbar()->setChild(
-                'delete_button',
-                $this->getLayout()->createBlock(
-                    'Magento\Backend\Block\Widget\Button'
-                )->setData(
-                    array(
-                        'label' => __('Delete Template'),
-                        'onclick' => 'templateControl.deleteTemplate();',
-                        'class' => 'delete'
-                    )
+            $this->buttonList->add(
+                'delete',
+                array(
+                    'label' => __('Delete Template'),
+                    'onclick' => 'templateControl.deleteTemplate();',
+                    'class' => 'delete'
                 )
             );
         }
         if (!$this->isTextType()) {
-            $this->getToolbar()->setChild(
-                'to_plain_button',
-                $this->getLayout()->createBlock(
-                    'Magento\Backend\Block\Widget\Button'
-                )->setData(
-                    array(
-                        'label' => __('Convert to Plain Text'),
-                        'onclick' => 'templateControl.stripTags();',
-                        'id' => 'convert_button'
-                    )
+            $this->buttonList->add(
+                'to_plain',
+                array(
+                    'label' => __('Convert to Plain Text'),
+                    'onclick' => 'templateControl.stripTags();',
+                    'id' => 'convert_button'
                 )
             );
-            $this->getToolbar()->setChild(
-                'to_html_button',
-                $this->getLayout()->createBlock(
-                    'Magento\Backend\Block\Widget\Button'
-                )->setData(
-                    array(
-                        'label' => __('Return Html Version'),
-                        'onclick' => 'templateControl.unStripTags();',
-                        'id' => 'convert_button_back',
-                        'style' => 'display:none'
-                    )
+            $this->buttonList->add(
+                'to_html',
+                array(
+                    'label' => __('Return Html Version'),
+                    'onclick' => 'templateControl.unStripTags();',
+                    'id' => 'convert_button_back',
+                    'style' => 'display:none'
                 )
             );
         }
-        $this->getToolbar()->setChild(
-            'preview_button',
-            $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Widget\Button'
-            )->setData(
-                array('label' => __('Preview Template'), 'onclick' => 'templateControl.preview();')
-            )
+        $this->buttonList->add(
+            'preview',
+            array('label' => __('Preview Template'), 'onclick' => 'templateControl.preview();')
         );
-        $this->getToolbar()->setChild(
-            'save_button',
-            $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Widget\Button'
-            )->setData(
-                array(
-                    'label' => __('Save Template'),
-                    'onclick' => 'templateControl.save();',
-                    'class' => 'save primary save-template'
-                )
+        $this->buttonList->add(
+            'save',
+            array(
+                'label' => __('Save Template'),
+                'onclick' => 'templateControl.save();',
+                'class' => 'save primary save-template'
             )
         );
-        $this->setChild(
-            'load_button',
-            $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Widget\Button'
-            )->setData(
-                array(
-                    'label' => __('Load Template'),
-                    'onclick' => 'templateControl.load();',
-                    'type' => 'button',
-                    'class' => 'save'
-                )
-            )
+        $this->buttonList->add(
+            'load',
+            array(
+                'label' => __('Load Template'),
+                'onclick' => 'templateControl.load();',
+                'type' => 'button',
+                'class' => 'save'
+            ),
+            0,
+            0,
+            null
         );
+        $this->toolbar->pushButtons($this, $this->buttonList);
         $this->addChild('form', 'Magento\Email\Block\Adminhtml\Template\Edit\Form');
         return parent::_prepareLayout();
     }
 
+    /**
+     *{@inheritdoc}
+     */
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    {
+        $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
+        return $this;
+    }
+
     /**
      * Collect, sort and set template options
      *
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
index 95fececde1f968a51c5235ed6dee95c59a759c77..3e56c09eb31402af72c29178f872f81b6f7b7220 100644
--- a/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template.php
@@ -47,228 +47,6 @@ class Template extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Email Templates'));
-
-        if ($this->getRequest()->getQuery('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Email::template');
-        $this->_addBreadcrumb(__('Transactional Emails'), __('Transactional Emails'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Grid action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * New transactional email action
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit transactional email action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_view->loadLayout();
-        $template = $this->_initTemplate('id');
-        $this->_setActiveMenu('Magento_Email::template');
-        $this->_addBreadcrumb(__('Transactional Emails'), __('Transactional Emails'), $this->getUrl('adminhtml/*'));
-
-        if ($this->getRequest()->getParam('id')) {
-            $this->_addBreadcrumb(__('Edit Template'), __('Edit System Template'));
-        } else {
-            $this->_addBreadcrumb(__('New Template'), __('New System Template'));
-        }
-
-        $this->_title->add($template->getId() ? $template->getTemplateCode() : __('New Template'));
-
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Email\Block\Adminhtml\Template\Edit',
-                'template_edit'
-            )->setEditMode(
-                (bool)$this->getRequest()->getParam('id')
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save transactional email action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $request = $this->getRequest();
-        $id = $this->getRequest()->getParam('id');
-
-        $template = $this->_initTemplate('id');
-        if (!$template->getId() && $id) {
-            $this->messageManager->addError(__('This email template no longer exists.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-
-        try {
-            $template->setTemplateSubject(
-                $request->getParam('template_subject')
-            )->setTemplateCode(
-                $request->getParam('template_code')
-            )->setTemplateText(
-                $request->getParam('template_text')
-            )->setTemplateStyles(
-                $request->getParam('template_styles')
-            )->setModifiedAt(
-                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
-            )->setOrigTemplateCode(
-                $request->getParam('orig_template_code')
-            )->setOrigTemplateVariables(
-                $request->getParam('orig_template_variables')
-            );
-
-            if (!$template->getId()) {
-                $template->setTemplateType(\Magento\Email\Model\Template::TYPE_HTML);
-            }
-
-            if ($request->getParam('_change_type_flag')) {
-                $template->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT);
-                $template->setTemplateStyles('');
-            }
-
-            $template->save();
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
-            $this->messageManager->addSuccess(__('The email template has been saved.'));
-            $this->_redirect('adminhtml/*');
-        } catch (\Exception $e) {
-            $this->_objectManager->get(
-                'Magento\Backend\Model\Session'
-            )->setData(
-                'email_template_form_data',
-                $request->getParams()
-            );
-            $this->messageManager->addError($e->getMessage());
-            $this->_forward('new');
-        }
-    }
-
-    /**
-     * Delete transactional email action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $template = $this->_initTemplate('id');
-        if ($template->getId()) {
-            try {
-                // check if the template is currently used
-                if (count($template->getSystemConfigPathsWhereUsedCurrently()) == 0) {
-                    $template->delete();
-                    // display success message
-                    $this->messageManager->addSuccess(__('The email template has been deleted.'));
-                    $this->_objectManager->get('Magento\Framework\App\ReinitableConfig')->reinit();
-                    // go to grid
-                    $this->_redirect('adminhtml/*/');
-                    return;
-                }
-                // display error  message
-                $this->messageManager->addError(__('The email template is currently being used.'));
-                // redirect to edit form
-                $this->_redirect('adminhtml/*/edit', array('id' => $template->getId()));
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('An error occurred while deleting email template data. Please review log and try again.')
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                // save data in session
-                $this->_objectManager->get(
-                    'Magento\Backend\Model\Session'
-                )->setFormData(
-                    $this->getRequest()->getParams()
-                );
-                // redirect to edit form
-                $this->_redirect('adminhtml/*/edit', array('id' => $template->getId()));
-                return;
-            }
-        }
-        // display error message
-        $this->messageManager->addError(__('We can\'t find an email template to delete.'));
-        // go to grid
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Preview transactional email action
-     *
-     * @return void
-     */
-    public function previewAction()
-    {
-        try {
-            $this->_view->loadLayout('systemPreview');
-            $this->_view->renderLayout();
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred. The email template can not be opened for preview.'));
-            $this->_redirect('adminhtml/*/');
-        }
-    }
-
-    /**
-     * Set template data to retrieve it in template info form
-     *
-     * @return void
-     */
-    public function defaultTemplateAction()
-    {
-        $this->_view->loadLayout();
-        $template = $this->_initTemplate('id');
-        $templateCode = $this->getRequest()->getParam('code');
-        try {
-            $template->loadDefault($templateCode);
-            $template->setData('orig_template_code', $templateCode);
-            $template->setData('template_variables', \Zend_Json::encode($template->getVariablesOptionArray(true)));
-
-            $templateBlock = $this->_view->getLayout()->createBlock('Magento\Email\Block\Adminhtml\Template\Edit');
-            $template->setData('orig_template_used_default_for', $templateBlock->getUsedDefaultForPaths(false));
-
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($template->getData())
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
     /**
      * Load email template from request
      *
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3c438179fc3ffaf7ba9d6dbbb81db7860853195
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/DefaultTemplate.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class DefaultTemplate extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Set template data to retrieve it in template info form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $template = $this->_initTemplate('id');
+        $templateCode = $this->getRequest()->getParam('code');
+        try {
+            $template->loadDefault($templateCode);
+            $template->setData('orig_template_code', $templateCode);
+            $template->setData('template_variables', \Zend_Json::encode($template->getVariablesOptionArray(true)));
+
+            $templateBlock = $this->_view->getLayout()->createBlock('Magento\Email\Block\Adminhtml\Template\Edit');
+            $template->setData('orig_template_used_default_for', $templateBlock->getUsedDefaultForPaths(false));
+
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($template->getData())
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..93628370c36c1a6fad2df66ed86d40f8cb9827ac
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Delete.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Delete extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Delete transactional email action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $template = $this->_initTemplate('id');
+        if ($template->getId()) {
+            try {
+                // check if the template is currently used
+                if (count($template->getSystemConfigPathsWhereUsedCurrently()) == 0) {
+                    $template->delete();
+                    // display success message
+                    $this->messageManager->addSuccess(__('The email template has been deleted.'));
+                    $this->_objectManager->get('Magento\Framework\App\ReinitableConfig')->reinit();
+                    // go to grid
+                    $this->_redirect('adminhtml/*/');
+                    return;
+                }
+                // display error  message
+                $this->messageManager->addError(__('The email template is currently being used.'));
+                // redirect to edit form
+                $this->_redirect('adminhtml/*/edit', array('id' => $template->getId()));
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('An error occurred while deleting email template data. Please review log and try again.')
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                // save data in session
+                $this->_objectManager->get(
+                    'Magento\Backend\Model\Session'
+                )->setFormData(
+                    $this->getRequest()->getParams()
+                );
+                // redirect to edit form
+                $this->_redirect('adminhtml/*/edit', array('id' => $template->getId()));
+                return;
+            }
+        }
+        // display error message
+        $this->messageManager->addError(__('We can\'t find an email template to delete.'));
+        // go to grid
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Edit.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..41f7d77177f4415c0f04fcd4dc910d4f7366ad59
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Edit.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Edit extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Edit transactional email action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $template = $this->_initTemplate('id');
+        $this->_setActiveMenu('Magento_Email::template');
+        $this->_addBreadcrumb(__('Transactional Emails'), __('Transactional Emails'), $this->getUrl('adminhtml/*'));
+
+        if ($this->getRequest()->getParam('id')) {
+            $this->_addBreadcrumb(__('Edit Template'), __('Edit System Template'));
+        } else {
+            $this->_addBreadcrumb(__('New Template'), __('New System Template'));
+        }
+
+        $this->_title->add($template->getId() ? $template->getTemplateCode() : __('New Template'));
+
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Email\Block\Adminhtml\Template\Edit',
+                'template_edit'
+            )->setEditMode(
+                (bool)$this->getRequest()->getParam('id')
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Grid.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..f18c4ef12520fb9e56f3c7dcc0b61ddeb205f4d1
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Grid extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Index.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4cfa4b0675f493b01c06c977a5f8cb0170c239f
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Index.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Index extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Email Templates'));
+
+        if ($this->getRequest()->getQuery('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Email::template');
+        $this->_addBreadcrumb(__('Transactional Emails'), __('Transactional Emails'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/NewAction.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..483aee6c2d2156f033b540dbcb8b18bb1d8e7d9f
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class NewAction extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * New transactional email action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php
new file mode 100644
index 0000000000000000000000000000000000000000..d37539125afb58bdcb5f775ed75f1d06c54ebfcb
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Preview.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Preview extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Preview transactional email action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_view->loadLayout('systemPreview');
+            $this->_view->renderLayout();
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred. The email template can not be opened for preview.'));
+            $this->_redirect('adminhtml/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Save.php b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..912bbbe474b3a71ea238bc382676a9bd376b6003
--- /dev/null
+++ b/app/code/Magento/Email/Controller/Adminhtml/Email/Template/Save.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Email\Controller\Adminhtml\Email\Template;
+
+class Save extends \Magento\Email\Controller\Adminhtml\Email\Template
+{
+    /**
+     * Save transactional email action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+        $id = $this->getRequest()->getParam('id');
+
+        $template = $this->_initTemplate('id');
+        if (!$template->getId() && $id) {
+            $this->messageManager->addError(__('This email template no longer exists.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+
+        try {
+            $template->setTemplateSubject(
+                $request->getParam('template_subject')
+            )->setTemplateCode(
+                $request->getParam('template_code')
+            )->setTemplateText(
+                $request->getParam('template_text')
+            )->setTemplateStyles(
+                $request->getParam('template_styles')
+            )->setModifiedAt(
+                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
+            )->setOrigTemplateCode(
+                $request->getParam('orig_template_code')
+            )->setOrigTemplateVariables(
+                $request->getParam('orig_template_variables')
+            );
+
+            if (!$template->getId()) {
+                $template->setTemplateType(\Magento\Email\Model\Template::TYPE_HTML);
+            }
+
+            if ($request->getParam('_change_type_flag')) {
+                $template->setTemplateType(\Magento\Framework\App\TemplateTypesInterface::TYPE_TEXT);
+                $template->setTemplateStyles('');
+            }
+
+            $template->save();
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+            $this->messageManager->addSuccess(__('The email template has been saved.'));
+            $this->_redirect('adminhtml/*');
+        } catch (\Exception $e) {
+            $this->_objectManager->get(
+                'Magento\Backend\Model\Session'
+            )->setData(
+                'email_template_form_data',
+                $request->getParams()
+            );
+            $this->messageManager->addError($e->getMessage());
+            $this->_forward('new');
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleAnalytics/Block/Ga.php b/app/code/Magento/GoogleAnalytics/Block/Ga.php
index 30ebc39fda8dbb7a41a3d75f277a747af22c17e0..47aa6223ad4409446b509247bb9525bfaa4d0463 100644
--- a/app/code/Magento/GoogleAnalytics/Block/Ga.php
+++ b/app/code/Magento/GoogleAnalytics/Block/Ga.php
@@ -24,7 +24,7 @@
 namespace Magento\GoogleAnalytics\Block;
 
 /**
- * GoogleAnalitics Page Block
+ * GoogleAnalytics Page Block
  */
 class Ga extends \Magento\Framework\View\Element\Template
 {
@@ -84,8 +84,8 @@ class Ga extends \Magento\Framework\View\Element\Template
      *
      * @param string $accountId
      * @return string
-     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApiBasicConfiguration.html#_gat.GA_Tracker_._trackPageview
-     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gaq.html
+     * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference#set
+     * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference#gaObjectMethods
      */
     public function getPageTrackingCode($accountId)
     {
@@ -94,15 +94,19 @@ class Ga extends \Magento\Framework\View\Element\Template
         if ($pageName && substr($pageName, 0, 1) == '/' && strlen($pageName) > 1) {
             $optPageURL = ", '{$this->escapeJsQuote($pageName)}'";
         }
-        return "\n_gaq.push(['_setAccount', '{$this->escapeJsQuote(
+
+        return "\nga('create', '{$this->escapeJsQuote(
             $accountId
-        )}']);\n_gaq.push(['_trackPageview'{$optPageURL}]);\n";
+        )}', 'auto');\nga('send', 'pageview'{$optPageURL});\n";
     }
 
     /**
      * Render information about specified orders and their items
      *
-     * @link http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEcommerce.html#_gat.GA_Tracker_._addTrans
+     * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#checkout-options
+     * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#measuring-transactions
+     * @link https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#transaction
+     *
      * @return string|void
      */
     public function getOrdersTrackingCode()
@@ -114,36 +118,47 @@ class Ga extends \Magento\Framework\View\Element\Template
 
         $collection = $this->_salesOrderCollection->create();
         $collection->addFieldToFilter('entity_id', array('in' => $orderIds));
-        $result = array();
+        $result = [];
+
+        $result[] = "ga('require', 'ec', 'ec.js');";
         foreach ($collection as $order) {
             if ($order->getIsVirtual()) {
                 $address = $order->getBillingAddress();
             } else {
                 $address = $order->getShippingAddress();
             }
-            $result[] = sprintf(
-                "_gaq.push(['_addTrans', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s']);",
-                $order->getIncrementId(),
-                $this->escapeJsQuote($this->_storeManager->getStore()->getFrontendName()),
-                $order->getBaseGrandTotal(),
-                $order->getBaseTaxAmount(),
-                $order->getBaseShippingAmount(),
-                $this->escapeJsQuote($this->escapeHtml($address->getCity())),
-                $this->escapeJsQuote($this->escapeHtml($address->getRegion())),
-                $this->escapeJsQuote($this->escapeHtml($address->getCountry()))
-            );
+
             foreach ($order->getAllVisibleItems() as $item) {
                 $result[] = sprintf(
-                    "_gaq.push(['_addItem', '%s', '%s', '%s', '%s', '%s', '%s']);",
-                    $order->getIncrementId(),
+                    "ga('ec:addProduct', {
+                        'id': '%s',
+                        'name': '%s',
+                        'price': '%s',
+                        'quantity': %s
+                    });",
                     $this->escapeJsQuote($item->getSku()),
                     $this->escapeJsQuote($item->getName()),
-                    null, // there is no "category" defined for the order item
                     $item->getBasePrice(),
                     $item->getQtyOrdered()
                 );
             }
-            $result[] = "_gaq.push(['_trackTrans']);";
+
+            $result[] = sprintf(
+                "ga('ec:setAction', 'purchase', {
+                    'id': '%s',
+                    'affiliation': '%s',
+                    'revenue': '%s',
+                    'tax': '%s',
+                    'shipping': '%s'
+                });",
+                $order->getIncrementId(),
+                $this->escapeJsQuote($this->_storeManager->getStore()->getFrontendName()),
+                $order->getBaseGrandTotal(),
+                $order->getBaseTaxAmount(),
+                $order->getBaseShippingAmount()
+            );
+
+            $result[] = "ga('send', 'pageview');";
         }
         return implode("\n", $result);
     }
diff --git a/app/code/Magento/GoogleAnalytics/view/frontend/templates/ga.phtml b/app/code/Magento/GoogleAnalytics/view/frontend/templates/ga.phtml
index a118e1a38fc0a00cadccd188841b3c7921ffb3aa..17a6a8db9730197f2a94f2857454995a8007ec1c 100644
--- a/app/code/Magento/GoogleAnalytics/view/frontend/templates/ga.phtml
+++ b/app/code/Magento/GoogleAnalytics/view/frontend/templates/ga.phtml
@@ -25,18 +25,17 @@
 <?php /** @var $this \Magento\GoogleAnalytics\Block\Ga */ ?>
 <?php if (!$this->helper('Magento\Store\Helper\Cookie')->isUserNotAllowSaveCookie()): ?>
 <?php $accountId = $this->getConfig(\Magento\GoogleAnalytics\Helper\Data::XML_PATH_ACCOUNT) ?>
-<!-- BEGIN GOOGLE ANALYTICS CODEs -->
+<!-- BEGIN GOOGLE ANALYTICS CODE -->
 <script type="text/javascript">
 //<![CDATA[
-    var _gaq = _gaq || [];
+    (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+    (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+    m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+    })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
     <?php echo $this->getPageTrackingCode($accountId) ?>
     <?php echo $this->getOrdersTrackingCode() ?>
 
-    (function() {
-        var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
-        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
-        var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
-    })();
 //]]>
 </script>
 <!-- END GOOGLE ANALYTICS CODE -->
diff --git a/app/code/Magento/GoogleShopping/Block/Adminhtml/Items.php b/app/code/Magento/GoogleShopping/Block/Adminhtml/Items.php
index 9ff065eb5883a299f7cc5d697ca8b84e46358f6c..abbde68012fb78e669d26e4353bfa95374102528 100644
--- a/app/code/Magento/GoogleShopping/Block/Adminhtml/Items.php
+++ b/app/code/Magento/GoogleShopping/Block/Adminhtml/Items.php
@@ -43,12 +43,12 @@ class Items extends \Magento\Backend\Block\Widget\Grid\Container
     protected $_flagFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\GoogleShopping\Model\FlagFactory $flagFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\GoogleShopping\Model\FlagFactory $flagFactory,
         array $data = array()
     ) {
diff --git a/app/code/Magento/GoogleShopping/Block/Adminhtml/Types/Edit.php b/app/code/Magento/GoogleShopping/Block/Adminhtml/Types/Edit.php
index 2bd05f9a620e51c5fc9b1b91f784263bcb156283..cf4fcde93b6dcd70b0657d30ea2c345b3e205182 100644
--- a/app/code/Magento/GoogleShopping/Block/Adminhtml/Types/Edit.php
+++ b/app/code/Magento/GoogleShopping/Block/Adminhtml/Types/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -59,12 +59,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml_types';
         $this->_mode = 'edit';
         $model = $this->_coreRegistry->registry('current_item_type');
-        $this->_removeButton('reset');
-        $this->_updateButton('save', 'label', __('Save Mapping'));
-        $this->_updateButton('save', 'id', 'save_button');
-        $this->_updateButton('delete', 'label', __('Delete Mapping'));
+        $this->buttonList->remove('reset');
+        $this->buttonList->update('save', 'label', __('Save Mapping'));
+        $this->buttonList->update('save', 'id', 'save_button');
+        $this->buttonList->update('delete', 'label', __('Delete Mapping'));
         if ($model && !$model->getId()) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
     }
 
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
index c92b4d9cc1feb96e91dc4def8a395f08c800cf47..512f6b69ab884e26b59e854482319ecaa0802973 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items.php
@@ -31,113 +31,6 @@ namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping;
  */
 class Items extends \Magento\Backend\App\Action
 {
-    /**
-     * Initialize general settings for action
-     *
-     * @return $this
-     */
-    protected function _initAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_GoogleShopping::catalog_googleshopping_items'
-        )->_addBreadcrumb(
-            __('Catalog'),
-            __('Catalog')
-        )->_addBreadcrumb(
-            __('Google Content'),
-            __('Google Content')
-        );
-        return $this;
-    }
-
-    /**
-     * Manage Items page with two item grids: Magento products and Google Content items
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Google Content Items'));
-
-        if (0 === (int)$this->getRequest()->getParam('store')) {
-            $this->_redirect(
-                'adminhtml/*/',
-                array(
-                    'store' => $this->_objectManager->get(
-                        'Magento\Store\Model\StoreManagerInterface'
-                    )->getStore()->getId(),
-                    '_current' => true
-                )
-            );
-            return;
-        }
-
-        $this->_initAction();
-
-        $contentBlock = $this->_view->getLayout()->createBlock(
-            'Magento\GoogleShopping\Block\Adminhtml\Items'
-        )->setStore(
-            $this->_getStore()
-        );
-
-        if ($this->getRequest()->getParam('captcha_token') && $this->getRequest()->getParam('captcha_url')) {
-            $contentBlock->setGcontentCaptchaToken(
-                $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->urlDecode(
-                    $this->getRequest()->getParam('captcha_token')
-                )
-            );
-            $contentBlock->setGcontentCaptchaUrl(
-                $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->urlDecode(
-                    $this->getRequest()->getParam('captcha_url')
-                )
-            );
-        }
-
-        if (!$this->_objectManager->get(
-            'Magento\GoogleShopping\Model\Config'
-        )->isValidDefaultCurrencyCode(
-            $this->_getStore()->getId()
-        )
-        ) {
-            $_countryInfo = $this->_objectManager->get(
-                'Magento\GoogleShopping\Model\Config'
-            )->getTargetCountryInfo(
-                $this->_getStore()->getId()
-            );
-            $this->messageManager->addNotice(
-                __(
-                    "The store's currency should be set to %1 for %2 in system configuration. Otherwise item prices won't be correct in Google Content.",
-                    $_countryInfo['currency_name'],
-                    $_countryInfo['name']
-                )
-            );
-        }
-
-        $this->_addBreadcrumb(__('Items'), __('Items'))->_addContent($contentBlock);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Grid with Google Content items
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout();
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\GoogleShopping\Block\Adminhtml\Items\Item'
-            )->setIndex(
-                $this->getRequest()->getParam('index')
-            )->toHtml()
-        );
-    }
 
     /**
      * Retrieve synchronization process mutex
@@ -149,212 +42,6 @@ class Items extends \Magento\Backend\App\Action
         return $this->_objectManager->get('Magento\GoogleShopping\Model\Flag')->loadSelf();
     }
 
-    /**
-     * Add (export) several products to Google Content
-     *
-     * @return void
-     */
-    public function massAddAction()
-    {
-        $flag = $this->_getFlag();
-        if ($flag->isLocked()) {
-            return;
-        }
-
-        session_write_close();
-        ignore_user_abort(true);
-        set_time_limit(0);
-
-        $storeId = $this->_getStore()->getId();
-        $productIds = $this->getRequest()->getParam('product', null);
-        $notifier = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox');
-
-        try {
-            $flag->lock();
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\MassOperations'
-            )->setFlag(
-                $flag
-            )->addProducts(
-                $productIds,
-                $storeId
-            );
-        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
-            // Google requires CAPTCHA for login
-            $this->messageManager->addError(__($e->getMessage()));
-            $flag->unlock();
-            $this->_redirectToCaptcha($e);
-            return;
-        } catch (\Exception $e) {
-            $flag->unlock();
-            $notifier->addMajor(
-                __('An error has occurred while adding products to google shopping account.'),
-                $e->getMessage()
-            );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            return;
-        }
-
-        $flag->unlock();
-    }
-
-    /**
-     * Delete products from Google Content
-     *
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $flag = $this->_getFlag();
-        if ($flag->isLocked()) {
-            return;
-        }
-
-        session_write_close();
-        ignore_user_abort(true);
-        set_time_limit(0);
-
-        $itemIds = $this->getRequest()->getParam('item');
-
-        try {
-            $flag->lock();
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\MassOperations'
-            )->setFlag(
-                $flag
-            )->deleteItems(
-                $itemIds
-            );
-        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
-            // Google requires CAPTCHA for login
-            $this->messageManager->addError(__($e->getMessage()));
-            $flag->unlock();
-            $this->_redirectToCaptcha($e);
-            return;
-        } catch (\Exception $e) {
-            $flag->unlock();
-            $this->_objectManager->create(
-                'Magento\AdminNotification\Model\Inbox'
-            )->addMajor(
-                __('An error has occurred while deleting products from google shopping account.'),
-                __(
-                    'One or more products were not deleted from google shopping account. Refer to the log file for details.'
-                )
-            );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            return;
-        }
-
-        $flag->unlock();
-    }
-
-    /**
-     * Update items statistics and remove the items which are not available in Google Content
-     *
-     * @return void
-     */
-    public function refreshAction()
-    {
-        $flag = $this->_getFlag();
-        if ($flag->isLocked()) {
-            return;
-        }
-
-        session_write_close();
-        ignore_user_abort(true);
-        set_time_limit(0);
-
-        $itemIds = $this->getRequest()->getParam('item');
-
-        try {
-            $flag->lock();
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\MassOperations'
-            )->setFlag(
-                $flag
-            )->synchronizeItems(
-                $itemIds
-            );
-        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
-            // Google requires CAPTCHA for login
-            $this->messageManager->addError(__($e->getMessage()));
-            $flag->unlock();
-            $this->_redirectToCaptcha($e);
-            return;
-        } catch (\Exception $e) {
-            $flag->unlock();
-            $this->_objectManager->create(
-                'Magento\AdminNotification\Model\Inbox'
-            )->addMajor(
-                __('An error has occurred while deleting products from google shopping account.'),
-                __(
-                    'One or more products were not deleted from google shopping account. Refer to the log file for details.'
-                )
-            );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            return;
-        }
-
-        $flag->unlock();
-    }
-
-    /**
-     * Confirm CAPTCHA
-     *
-     * @return void
-     */
-    public function confirmCaptchaAction()
-    {
-
-        $storeId = $this->_getStore()->getId();
-        try {
-            $this->_objectManager->create(
-                'Magento\GoogleShopping\Model\Service'
-            )->getClient(
-                $storeId,
-                $this->_objectManager->get(
-                    'Magento\Core\Helper\Data'
-                )->urlDecode(
-                    $this->getRequest()->getParam('captcha_token')
-                ),
-                $this->getRequest()->getParam('user_confirm')
-            );
-            $this->messageManager->addSuccess(__('Captcha has been confirmed.'));
-        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
-            $this->messageManager->addError(__('There was a Captcha confirmation error: %1', $e->getMessage()));
-            $this->_redirectToCaptcha($e);
-            return;
-        } catch (\Zend_Gdata_App_Exception $e) {
-            $this->messageManager->addError(
-                $this->_objectManager->get(
-                    'Magento\GoogleShopping\Helper\Data'
-                )->parseGdataExceptionMessage(
-                    $e->getMessage()
-                )
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__('Something went wrong during Captcha confirmation.'));
-        }
-
-        $this->_redirect('adminhtml/*/index', array('store' => $storeId));
-    }
-
-    /**
-     * Retrieve background process status
-     *
-     * @return \Zend_Controller_Response_Abstract
-     */
-    public function statusAction()
-    {
-        if ($this->getRequest()->isAjax()) {
-            $params = array('is_running' => $this->_getFlag()->isLocked());
-            return $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($params)
-            );
-        }
-    }
-
     /**
      * Redirect user to Google Captcha challenge
      *
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
new file mode 100644
index 0000000000000000000000000000000000000000..abd5855c5695feff64f77f5afa5aff4b97fbbc48
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/ConfirmCaptcha.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class ConfirmCaptcha extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Confirm CAPTCHA
+     *
+     * @return void
+     */
+    public function execute()
+    {
+
+        $storeId = $this->_getStore()->getId();
+        try {
+            $this->_objectManager->create(
+                'Magento\GoogleShopping\Model\Service'
+            )->getClient(
+                $storeId,
+                $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->urlDecode(
+                    $this->getRequest()->getParam('captcha_token')
+                ),
+                $this->getRequest()->getParam('user_confirm')
+            );
+            $this->messageManager->addSuccess(__('Captcha has been confirmed.'));
+        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
+            $this->messageManager->addError(__('There was a Captcha confirmation error: %1', $e->getMessage()));
+            $this->_redirectToCaptcha($e);
+            return;
+        } catch (\Zend_Gdata_App_Exception $e) {
+            $this->messageManager->addError(
+                $this->_objectManager->get(
+                    'Magento\GoogleShopping\Helper\Data'
+                )->parseGdataExceptionMessage(
+                    $e->getMessage()
+                )
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__('Something went wrong during Captcha confirmation.'));
+        }
+
+        $this->_redirect('adminhtml/*/index', array('store' => $storeId));
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Grid.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a1942938eb5523cabbccb8c74222408965c3b13
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Grid.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class Grid extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Grid with Google Content items
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\GoogleShopping\Block\Adminhtml\Items\Item'
+            )->setIndex(
+                $this->getRequest()->getParam('index')
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Index.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa10e9f73a6faaae914b69f1c74ae6be2bb540e6
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Index.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Initialize general settings for action
+     *
+     * @return $this
+     */
+    protected function _initAction()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_GoogleShopping::catalog_googleshopping_items'
+        )->_addBreadcrumb(
+            __('Catalog'),
+            __('Catalog')
+        )->_addBreadcrumb(
+            __('Google Content'),
+            __('Google Content')
+        );
+        return $this;
+    }
+
+    /**
+     * Manage Items page with two item grids: Magento products and Google Content items
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Google Content Items'));
+
+        if (0 === (int)$this->getRequest()->getParam('store')) {
+            $this->_redirect(
+                'adminhtml/*/',
+                array(
+                    'store' => $this->_objectManager->get(
+                        'Magento\Store\Model\StoreManagerInterface'
+                    )->getStore()->getId(),
+                    '_current' => true
+                )
+            );
+            return;
+        }
+
+        $this->_initAction();
+
+        $contentBlock = $this->_view->getLayout()->createBlock(
+            'Magento\GoogleShopping\Block\Adminhtml\Items'
+        )->setStore(
+            $this->_getStore()
+        );
+
+        if ($this->getRequest()->getParam('captcha_token') && $this->getRequest()->getParam('captcha_url')) {
+            $contentBlock->setGcontentCaptchaToken(
+                $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->urlDecode(
+                    $this->getRequest()->getParam('captcha_token')
+                )
+            );
+            $contentBlock->setGcontentCaptchaUrl(
+                $this->_objectManager->get(
+                    'Magento\Core\Helper\Data'
+                )->urlDecode(
+                    $this->getRequest()->getParam('captcha_url')
+                )
+            );
+        }
+
+        if (!$this->_objectManager->get(
+            'Magento\GoogleShopping\Model\Config'
+        )->isValidDefaultCurrencyCode(
+            $this->_getStore()->getId()
+        )
+        ) {
+            $_countryInfo = $this->_objectManager->get(
+                'Magento\GoogleShopping\Model\Config'
+            )->getTargetCountryInfo(
+                $this->_getStore()->getId()
+            );
+            $this->messageManager->addNotice(
+                __(
+                    "The store's currency should be set to %1 for %2 in system configuration. Otherwise item prices won't be correct in Google Content.",
+                    $_countryInfo['currency_name'],
+                    $_countryInfo['name']
+                )
+            );
+        }
+
+        $this->_addBreadcrumb(__('Items'), __('Items'))->_addContent($contentBlock);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b8245af5f0ca0a28ceaf098517b45bdab118ada
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassAdd.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class MassAdd extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Add (export) several products to Google Content
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $flag = $this->_getFlag();
+        if ($flag->isLocked()) {
+            return;
+        }
+
+        session_write_close();
+        ignore_user_abort(true);
+        set_time_limit(0);
+
+        $storeId = $this->_getStore()->getId();
+        $productIds = $this->getRequest()->getParam('product', null);
+        $notifier = $this->_objectManager->create('Magento\AdminNotification\Model\Inbox');
+
+        try {
+            $flag->lock();
+            $this->_objectManager->create(
+                'Magento\GoogleShopping\Model\MassOperations'
+            )->setFlag(
+                $flag
+            )->addProducts(
+                $productIds,
+                $storeId
+            );
+        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
+            // Google requires CAPTCHA for login
+            $this->messageManager->addError(__($e->getMessage()));
+            $flag->unlock();
+            $this->_redirectToCaptcha($e);
+            return;
+        } catch (\Exception $e) {
+            $flag->unlock();
+            $notifier->addMajor(
+                __('An error has occurred while adding products to google shopping account.'),
+                $e->getMessage()
+            );
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            return;
+        }
+
+        $flag->unlock();
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassDelete.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..022491f73639a7ef0c307ba2698410746fbac523
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/MassDelete.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Delete products from Google Content
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class MassDelete extends Refresh
+{
+    /**
+     * Name of the operation to execute
+     *
+     * @var string
+     */
+    protected $operation = 'deleteItems';
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb294d6af1e3c2f59a1ca6da5a7335453a48e874
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Refresh.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Update items statistics and remove the items which are not available in Google Content
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class Refresh extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Name of the operation to execute
+     *
+     * @var string
+     */
+    protected $operation = 'synchronizeItems';
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        $flag = $this->_getFlag();
+        if ($flag->isLocked()) {
+            return;
+        }
+
+        session_write_close();
+        ignore_user_abort(true);
+        set_time_limit(0);
+
+        $itemIds = $this->getRequest()->getParam('item');
+
+        try {
+            $flag->lock();
+            $operation = $this->operation;
+            $this->_objectManager->create(
+                'Magento\GoogleShopping\Model\MassOperations'
+            )->setFlag(
+                $flag
+            )->$operation(
+                $itemIds
+            );
+        } catch (\Zend_Gdata_App_CaptchaRequiredException $e) {
+            // Google requires CAPTCHA for login
+            $this->messageManager->addError(__($e->getMessage()));
+            $flag->unlock();
+            $this->_redirectToCaptcha($e);
+            return;
+        } catch (\Exception $e) {
+            $flag->unlock();
+            $this->_objectManager->create(
+                'Magento\AdminNotification\Model\Inbox'
+            )->addMajor(
+                __('An error has occurred while deleting products from google shopping account.'),
+                __(
+                    'One or more products were not deleted from google shopping account. Refer to the log file for details.'
+                )
+            );
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            return;
+        }
+
+        $flag->unlock();
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php
new file mode 100644
index 0000000000000000000000000000000000000000..266e88ce88276c6a4216a0b079eeb6bba7716383
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Items/Status.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items;
+
+class Status extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Items
+{
+    /**
+     * Retrieve background process status
+     *
+     * @return \Zend_Controller_Response_Abstract
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->isAjax()) {
+            $this->getResponse()->setHeader('Content-Type', 'application/json');
+            $params = array('is_running' => $this->_getFlag()->isLocked());
+            return $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($params)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Grid.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..5711d9594c45469eba5595e0777cd09577724810
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Grid.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Selection;
+
+class Grid extends \Magento\Backend\App\Action
+{
+    /**
+     * Grid with available products for Google Content
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\GoogleShopping\Block\Adminhtml\Items\Product'
+            )->setIndex(
+                $this->getRequest()->getParam('index')
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
similarity index 68%
rename from app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection.php
rename to app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
index 3ebf5d4af59440a4dc4f3587a2ecd9aac8fda056..fa7922b025d33943791b78d17d0553f40e9d1894 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Selection/Search.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping;
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Selection;
 
-/**
- * GoogleShopping Products selection grid controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Selection extends \Magento\Backend\App\Action
+class Search extends \Magento\Backend\App\Action
 {
     /**
      * Search result grid with available products for Google Content
      *
      * @return void
      */
-    public function searchAction()
+    public function execute()
     {
         $this->getResponse()->setBody(
             $this->_view->getLayout()->createBlock(
@@ -47,21 +43,4 @@ class Selection extends \Magento\Backend\App\Action
             )->toHtml()
         );
     }
-
-    /**
-     * Grid with available products for Google Content
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout();
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\GoogleShopping\Block\Adminhtml\Items\Product'
-            )->setIndex(
-                $this->getRequest()->getParam('index')
-            )->toHtml()
-        );
-    }
 }
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
index 66ce7ba240b2865391c68915937e124e11362b57..f4d3e8a2cee1013aaf66ce4fc57479c0dd753086 100644
--- a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types.php
@@ -105,237 +105,6 @@ class Types extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * List of all maps (items)
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Google Content Attributes'));
-
-        $this->_initAction()->_addBreadcrumb(__('Attribute Maps'), __('Attribute Maps'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Grid for AJAX request
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout('false');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new attribute set mapping
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        try {
-            $this->_initItemType();
-
-            $this->_title->add(__('New Google Content Attribute Mapping'));
-
-            $this->_initAction()->_addBreadcrumb(
-                __('New attribute set mapping'),
-                __('New attribute set mapping')
-            )->_addContent(
-                $this->_view->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
-            );
-            $this->_view->renderLayout();
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__("We can't create Attribute Set Mapping."));
-            $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
-        }
-    }
-
-    /**
-     * Edit attribute set mapping
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_initItemType();
-        $typeId = $this->_coreRegistry->registry('current_item_type')->getTypeId();
-
-        try {
-            $result = array();
-            if ($typeId) {
-                $collection = $this->_objectManager->create(
-                    'Magento\GoogleShopping\Model\Resource\Attribute\Collection'
-                )->addTypeFilter(
-                    $typeId
-                )->load();
-                foreach ($collection as $attribute) {
-                    $result[] = $attribute->getData();
-                }
-            }
-
-            $this->_title->add(__('Google Content Attribute Mapping'));
-            $this->_coreRegistry->register('attributes', $result);
-
-            $breadcrumbLabel = $typeId ? __('Edit attribute set mapping') : __('New attribute set mapping');
-            $this->_initAction()->_addBreadcrumb(
-                $breadcrumbLabel,
-                $breadcrumbLabel
-            )->_addContent(
-                $this->_view->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
-            );
-            $this->_view->renderLayout();
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__("We can't edit Attribute Set Mapping."));
-            $this->_redirect('adminhtml/*/index');
-        }
-    }
-
-    /**
-     * Save attribute set mapping
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        /** @var $typeModel \Magento\GoogleShopping\Model\Type */
-        $typeModel = $this->_objectManager->create('Magento\GoogleShopping\Model\Type');
-        $id = $this->getRequest()->getParam('type_id');
-        if (!is_null($id)) {
-            $typeModel->load($id);
-        }
-
-        try {
-            $typeModel->setCategory($this->getRequest()->getParam('category'));
-            if ($typeModel->getId()) {
-                $collection = $this->_objectManager->create(
-                    'Magento\GoogleShopping\Model\Resource\Attribute\Collection'
-                )->addTypeFilter(
-                    $typeModel->getId()
-                )->load();
-                foreach ($collection as $attribute) {
-                    $attribute->delete();
-                }
-            } else {
-                $typeModel->setAttributeSetId(
-                    $this->getRequest()->getParam('attribute_set_id')
-                )->setTargetCountry(
-                    $this->getRequest()->getParam('target_country')
-                );
-            }
-            $typeModel->save();
-
-            $attributes = $this->getRequest()->getParam('attributes');
-            $requiredAttributes = $this->_objectManager->get(
-                'Magento\GoogleShopping\Model\Config'
-            )->getRequiredAttributes();
-            if (is_array($attributes)) {
-                $typeId = $typeModel->getId();
-                foreach ($attributes as $attrInfo) {
-                    if (isset($attrInfo['delete']) && $attrInfo['delete'] == 1) {
-                        continue;
-                    }
-                    $this->_objectManager->create(
-                        'Magento\GoogleShopping\Model\Attribute'
-                    )->setAttributeId(
-                        $attrInfo['attribute_id']
-                    )->setGcontentAttribute(
-                        $attrInfo['gcontent_attribute']
-                    )->setTypeId(
-                        $typeId
-                    )->save();
-                    unset($requiredAttributes[$attrInfo['gcontent_attribute']]);
-                }
-            }
-
-            $this->messageManager->addSuccess(__('The attribute mapping has been saved.'));
-            if (!empty($requiredAttributes)) {
-                $this->messageManager->addSuccess(
-                    $this->_objectManager->get('Magento\GoogleShopping\Helper\Category')->getMessage()
-                );
-            }
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__("We can't save Attribute Set Mapping."));
-        }
-        $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
-    }
-
-    /**
-     * Delete attribute set mapping
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        try {
-            $id = $this->getRequest()->getParam('id');
-            $model = $this->_objectManager->create('Magento\GoogleShopping\Model\Type');
-            $model->load($id);
-            if ($model->getTypeId()) {
-                $model->delete();
-            }
-            $this->messageManager->addSuccess(__('Attribute set mapping was deleted'));
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__("We can't delete Attribute Set Mapping."));
-        }
-        $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
-    }
-
-    /**
-     * Get Google Content attributes list
-     *
-     * @return void
-     */
-    public function loadAttributesAction()
-    {
-        try {
-            $this->getResponse()->setBody(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Attributes'
-                )->setAttributeSetId(
-                    $this->getRequest()->getParam('attribute_set_id')
-                )->setTargetCountry(
-                    $this->getRequest()->getParam('target_country')
-                )->setAttributeSetSelected(
-                    true
-                )->toHtml()
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            // just need to output text with error
-            $this->messageManager->addError(__("We can't load attributes."));
-        }
-    }
-
-    /**
-     * Get available attribute sets
-     *
-     * @return void
-     */
-    protected function loadAttributeSetsAction()
-    {
-        try {
-            $this->getResponse()->setBody(
-                $this->_view->getLayout()->getBlockSingleton(
-                    'Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Form'
-                )->getAttributeSetsSelectElement(
-                    $this->getRequest()->getParam('target_country')
-                )->toHtml()
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            // just need to output text with error
-            $this->messageManager->addError(__("We can't load attribute sets."));
-        }
-    }
-
     /**
      * Get store object, basing on request
      *
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..1fc85188877f3ca166cfead774900e385c6addb7
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Delete.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class Delete extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Delete attribute set mapping
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $id = $this->getRequest()->getParam('id');
+            $model = $this->_objectManager->create('Magento\GoogleShopping\Model\Type');
+            $model->load($id);
+            if ($model->getTypeId()) {
+                $model->delete();
+            }
+            $this->messageManager->addSuccess(__('Attribute set mapping was deleted'));
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__("We can't delete Attribute Set Mapping."));
+        }
+        $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b40720988959f0dc2b5b48ad2c72a05d77ad07c
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Edit.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class Edit extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Edit attribute set mapping
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initItemType();
+        $typeId = $this->_coreRegistry->registry('current_item_type')->getTypeId();
+
+        try {
+            $result = array();
+            if ($typeId) {
+                $collection = $this->_objectManager->create(
+                    'Magento\GoogleShopping\Model\Resource\Attribute\Collection'
+                )->addTypeFilter(
+                    $typeId
+                )->load();
+                foreach ($collection as $attribute) {
+                    $result[] = $attribute->getData();
+                }
+            }
+
+            $this->_title->add(__('Google Content Attribute Mapping'));
+            $this->_coreRegistry->register('attributes', $result);
+
+            $breadcrumbLabel = $typeId ? __('Edit attribute set mapping') : __('New attribute set mapping');
+            $this->_initAction()->_addBreadcrumb(
+                $breadcrumbLabel,
+                $breadcrumbLabel
+            )->_addContent(
+                $this->_view->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
+            );
+            $this->_view->renderLayout();
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__("We can't edit Attribute Set Mapping."));
+            $this->_redirect('adminhtml/*/index');
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Grid.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..f421ecc5391302c87c8bb7265ac3f44bc61729ba
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class Grid extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Grid for AJAX request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout('false');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..47860c99a3b910b21a2593a4bba81f01246c4f4e
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class Index extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * List of all maps (items)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Google Content Attributes'));
+
+        $this->_initAction()->_addBreadcrumb(__('Attribute Maps'), __('Attribute Maps'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..45c9a5fed4dc4f897658ef3ecda22b656e749036
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributeSetsAction.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class LoadAttributeSetsAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Get available attribute sets
+     *
+     * @return void
+     */
+    protected function execute()
+    {
+        try {
+            $this->getResponse()->setBody(
+                $this->_view->getLayout()->getBlockSingleton(
+                    'Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Form'
+                )->getAttributeSetsSelectElement(
+                    $this->getRequest()->getParam('target_country')
+                )->toHtml()
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            // just need to output text with error
+            $this->messageManager->addError(__("We can't load attribute sets."));
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
new file mode 100644
index 0000000000000000000000000000000000000000..b25c05ab848ab6c64c6bb3a037dd0c1eb46165ab
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/LoadAttributes.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class LoadAttributes extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Get Google Content attributes list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getResponse()->setBody(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\GoogleShopping\Block\Adminhtml\Types\Edit\Attributes'
+                )->setAttributeSetId(
+                    $this->getRequest()->getParam('attribute_set_id')
+                )->setTargetCountry(
+                    $this->getRequest()->getParam('target_country')
+                )->setAttributeSetSelected(
+                    true
+                )->toHtml()
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            // just need to output text with error
+            $this->messageManager->addError(__("We can't load attributes."));
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f38a68832fbd8797f68261d5a67772d99406c0f
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/NewAction.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class NewAction extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Create new attribute set mapping
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initItemType();
+
+            $this->_title->add(__('New Google Content Attribute Mapping'));
+
+            $this->_initAction()->_addBreadcrumb(
+                __('New attribute set mapping'),
+                __('New attribute set mapping')
+            )->_addContent(
+                $this->_view->getLayout()->createBlock('Magento\GoogleShopping\Block\Adminhtml\Types\Edit')
+            );
+            $this->_view->renderLayout();
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__("We can't create Attribute Set Mapping."));
+            $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
+        }
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c662179177799da8a7d4797a33115fef6fe5a0d
--- /dev/null
+++ b/app/code/Magento/GoogleShopping/Controller/Adminhtml/Googleshopping/Types/Save.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types;
+
+class Save extends \Magento\GoogleShopping\Controller\Adminhtml\Googleshopping\Types
+{
+    /**
+     * Save attribute set mapping
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $typeModel \Magento\GoogleShopping\Model\Type */
+        $typeModel = $this->_objectManager->create('Magento\GoogleShopping\Model\Type');
+        $id = $this->getRequest()->getParam('type_id');
+        if (!is_null($id)) {
+            $typeModel->load($id);
+        }
+
+        try {
+            $typeModel->setCategory($this->getRequest()->getParam('category'));
+            if ($typeModel->getId()) {
+                $collection = $this->_objectManager->create(
+                    'Magento\GoogleShopping\Model\Resource\Attribute\Collection'
+                )->addTypeFilter(
+                    $typeModel->getId()
+                )->load();
+                foreach ($collection as $attribute) {
+                    $attribute->delete();
+                }
+            } else {
+                $typeModel->setAttributeSetId(
+                    $this->getRequest()->getParam('attribute_set_id')
+                )->setTargetCountry(
+                    $this->getRequest()->getParam('target_country')
+                );
+            }
+            $typeModel->save();
+
+            $attributes = $this->getRequest()->getParam('attributes');
+            $requiredAttributes = $this->_objectManager->get(
+                'Magento\GoogleShopping\Model\Config'
+            )->getRequiredAttributes();
+            if (is_array($attributes)) {
+                $typeId = $typeModel->getId();
+                foreach ($attributes as $attrInfo) {
+                    if (isset($attrInfo['delete']) && $attrInfo['delete'] == 1) {
+                        continue;
+                    }
+                    $this->_objectManager->create(
+                        'Magento\GoogleShopping\Model\Attribute'
+                    )->setAttributeId(
+                        $attrInfo['attribute_id']
+                    )->setGcontentAttribute(
+                        $attrInfo['gcontent_attribute']
+                    )->setTypeId(
+                        $typeId
+                    )->save();
+                    unset($requiredAttributes[$attrInfo['gcontent_attribute']]);
+                }
+            }
+
+            $this->messageManager->addSuccess(__('The attribute mapping has been saved.'));
+            if (!empty($requiredAttributes)) {
+                $this->messageManager->addSuccess(
+                    $this->_objectManager->get('Magento\GoogleShopping\Helper\Category')->getMessage()
+                );
+            }
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__("We can't save Attribute Set Mapping."));
+        }
+        $this->_redirect('adminhtml/*/index', array('store' => $this->_getStore()->getId()));
+    }
+}
diff --git a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
index cf5ee78a90e24332a8caebfab9579c2e519d0a03..f2e4c0173dd3877504c92050f0fa8a3956094e0d 100644
--- a/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
+++ b/app/code/Magento/GoogleShopping/Model/Attribute/Tax.php
@@ -40,6 +40,11 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
      */
     protected $_taxData = null;
 
+    /**
+     * @var \Magento\Tax\Model\Calculation
+     */
+    protected $calculation;
+
     /**
      * Config
      *
@@ -57,6 +62,7 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
      * @param \Magento\GoogleShopping\Model\Resource\Attribute $resource
      * @param \Magento\GoogleShopping\Model\Config $config
      * @param \Magento\Tax\Helper\Data $taxData
+     * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
      */
@@ -70,11 +76,13 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
         \Magento\GoogleShopping\Model\Resource\Attribute $resource,
         \Magento\GoogleShopping\Model\Config $config,
         \Magento\Tax\Helper\Data $taxData,
+        \Magento\Tax\Model\Calculation $calculation,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
     ) {
         $this->_config = $config;
         $this->_taxData = $taxData;
+        $this->calculation = $calculation;
         parent::__construct(
             $context,
             $registry,
@@ -102,7 +110,7 @@ class Tax extends \Magento\GoogleShopping\Model\Attribute\DefaultAttribute
             return $entry;
         }
 
-        $calc = $this->_taxData->getCalculator();
+        $calc = $this->calculation;
         $customerTaxClass = $calc->getDefaultCustomerTaxClass($product->getStoreId());
         $rates = $calc->getRatesByCustomerAndProductTaxClasses($customerTaxClass, $product->getTaxClassId());
         $targetCountry = $this->_config->getTargetCountry($product->getStoreId());
diff --git a/app/code/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/Grouped.php b/app/code/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/Grouped.php
index c3697d7d01060542c7a593650a305291fe53acdc..be12f61a002c89198a35e57034ae9911d9e60a35 100644
--- a/app/code/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/Grouped.php
@@ -35,11 +35,6 @@ use Magento\Customer\Service\V1\CustomerAccountServiceInterface as CustomerAccou
  */
 class Grouped extends \Magento\GroupedProduct\Block\Product\View\Type\Grouped
 {
-    /**
-     * @var \Magento\Catalog\Helper\Product\Price
-     */
-    protected $priceHelper;
-
     /**
      * @var string
      */
@@ -58,7 +53,6 @@ class Grouped extends \Magento\GroupedProduct\Block\Product\View\Type\Grouped
     /**
      * @param \Magento\Catalog\Block\Product\Context $context
      * @param \Magento\Framework\Stdlib\ArrayUtils $arrayUtils
-     * @param \Magento\Catalog\Helper\Product\Price $priceHelper
      * @param \Magento\Core\Helper\Data $coreHelper
      * @param CustomerAccountService $customerAccountService
      * @param array $data
@@ -66,14 +60,12 @@ class Grouped extends \Magento\GroupedProduct\Block\Product\View\Type\Grouped
     public function __construct(
         \Magento\Catalog\Block\Product\Context $context,
         \Magento\Framework\Stdlib\ArrayUtils $arrayUtils,
-        \Magento\Catalog\Helper\Product\Price $priceHelper,
         \Magento\Core\Helper\Data $coreHelper,
         CustomerAccountService $customerAccountService,
         array $data = array()
     ) {
         $this->_customerAccountService = $customerAccountService;
         $this->_coreHelper = $coreHelper;
-        $this->priceHelper = $priceHelper;
         parent::__construct(
             $context,
             $arrayUtils,
@@ -93,13 +85,6 @@ class Grouped extends \Magento\GroupedProduct\Block\Product\View\Type\Grouped
 
         $this->_block = 'Magento\Catalog\Block\Adminhtml\Product\Price';
         $this->_useLinkForAsLowAs = false;
-
-        if (is_null($this->priceHelper->getCustomer()->getId())
-            && $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID)
-        ) {
-            $customerId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_CUSTOMER_ID);
-            $this->priceHelper->setCustomer($this->_customerAccountService->getCustomer($customerId));
-        }
     }
 
     /**
diff --git a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit.php b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
similarity index 95%
rename from app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit.php
rename to app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
index fb941e8ea0be31ff841c6dc2fd11bef52bda480e..59bf5263490db7090ff05514d7c836193e116aca 100644
--- a/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit.php
+++ b/app/code/Magento/GroupedProduct/Controller/Adminhtml/Edit/Popup.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\GroupedProduct\Controller\Adminhtml;
+namespace Magento\GroupedProduct\Controller\Adminhtml\Edit;
 
-class Edit extends \Magento\Backend\App\AbstractAction
+class Popup extends \Magento\Backend\App\AbstractAction
 {
     /**
      * @var \Magento\Framework\Registry
@@ -73,7 +74,7 @@ class Edit extends \Magento\Backend\App\AbstractAction
      *
      * @return void
      */
-    public function popupAction()
+    public function execute()
     {
         $productId = (int)$this->getRequest()->getParam('id');
 
diff --git a/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php b/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php
index 092f1a07b9d2fa104f67c93f30e52b0cb5c54857..612156b93aa3d3f8388397310612bf85d7e47363 100644
--- a/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php
+++ b/app/code/Magento/GroupedProduct/Model/Sales/AdminOrder/Product/Quote/Plugin/Initializer.php
@@ -54,7 +54,7 @@ class Initializer
         $item = $proceed($quote, $product, $config);
 
         if (is_string($item) && $product->getTypeId() != Grouped::TYPE_CODE) {
-            $item = $quote->addProductAdvanced(
+            $item = $quote->addProduct(
                 $product,
                 $config,
                 \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_LITE
diff --git a/app/code/Magento/GroupedProduct/view/adminhtml/templates/catalog/product/composite/fieldset/grouped.phtml b/app/code/Magento/GroupedProduct/view/adminhtml/templates/catalog/product/composite/fieldset/grouped.phtml
index e8252e5a43ece6ce5524c90758f90a0011c8f892..a8c10055c84f65a85886a718edef2db39cddcf80 100644
--- a/app/code/Magento/GroupedProduct/view/adminhtml/templates/catalog/product/composite/fieldset/grouped.phtml
+++ b/app/code/Magento/GroupedProduct/view/adminhtml/templates/catalog/product/composite/fieldset/grouped.phtml
@@ -53,7 +53,7 @@
             <?php if ($_hasAssociatedProducts): ?>
                 <?php $i = 0 ?>
             <?php foreach ($_associatedProducts as $_item): ?>
-                <?php $_finalPriceInclTax = $this->helper('Magento\Catalog\Helper\Product\Price')->getPrice($_item, $_item->getFinalPrice(), true) ?>
+                <?php $_finalPriceInclTax = $this->helper('Magento\Tax\Helper\Data')->getPrice($_item, $_item->getFinalPrice(), true) ?>
                 <tr class="<?php echo (++$i % 2) ? 'even' : 'odd' ?>">
                     <td class="col-id"><?php echo $_item->getId() ?></td>
                     <td class="col-sku"><?php echo $this->escapeHtml($_item->getSku()) ?></td>
diff --git a/app/code/Magento/GroupedProduct/view/frontend/templates/product/price.phtml b/app/code/Magento/GroupedProduct/view/frontend/templates/product/price.phtml
index 111c5b4780f3bc0c434451c4a0d491c215e8b158..eb2f83a9815a4c7b42e768da1920a5f338ca78a1 100644
--- a/app/code/Magento/GroupedProduct/view/frontend/templates/product/price.phtml
+++ b/app/code/Magento/GroupedProduct/view/frontend/templates/product/price.phtml
@@ -29,8 +29,8 @@
 <?php
 /* @var $_coreHelper \Magento\Core\Helper\Data */
 $_coreHelper = $this->helper('Magento\Core\Helper\Data');
-/* @var $priceHelper \Magento\Catalog\Helper\Product\Price */
-$priceHelper  = $this->helper('Magento\Catalog\Helper\Product\Price');
+/* @var $taxHelper \Magento\Tax\Helper\Data */
+$taxHelper  = $this->helper('Magento\Tax\Helper\Data');
 
 $_product = $this->getProduct();
 $_id = $_product->getId();
@@ -38,13 +38,13 @@ $_minimalPriceValue = $_product->getMinimalPrice();
 $showMinPrice = $this->getDisplayMinimalPrice();
 
 if ($showMinPrice && $_minimalPriceValue) {
-    $_exclTax = $priceHelper->getPrice($_product, $_minimalPriceValue);
-    $_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, true);
+    $_exclTax = $taxHelper->getPrice($_product, $_minimalPriceValue);
+    $_inclTax = $taxHelper->getPrice($_product, $_minimalPriceValue, true);
     $price    = $showMinPrice ? $_minimalPriceValue : 0;
 } else {
     $price    = $_product->getFinalPrice();
-    $_exclTax = $priceHelper->getPrice($_product, $price);
-    $_inclTax = $priceHelper->getPrice($_product, $price, true);
+    $_exclTax = $taxHelper->getPrice($_product, $price);
+    $_inclTax = $taxHelper->getPrice($_product, $price, true);
 }
 ?>
 
@@ -54,7 +54,7 @@ if ($showMinPrice && $_minimalPriceValue) {
             <?php if ($showMinPrice): ?>
                 <span class="price-label"><?php echo __('Starting at:') ?></span>
             <?php endif ?>
-            <?php if ($priceHelper->displayBothPrices()): ?>
+            <?php if ($taxHelper->displayBothPrices()): ?>
                 <span class="price-excluding-tax">
                         <span class="label"><?php echo __('Excl. Tax:') ?></span>
                         <span class="price" id="price-excluding-tax-<?php echo $_id ?><?php echo $this->getIdSuffix() ?>" itemprop="price">
@@ -70,7 +70,7 @@ if ($showMinPrice && $_minimalPriceValue) {
             <?php else: ?>
                 <?php
                 $_showPrice = $_inclTax;
-                if (!$priceHelper->displayPriceIncludingTax()) {
+                if (!$taxHelper->displayPriceIncludingTax()) {
                     $_showPrice = $_exclTax;
                 }
                 ?>
diff --git a/app/code/Magento/GroupedProduct/view/frontend/templates/rss/product/price.phtml b/app/code/Magento/GroupedProduct/view/frontend/templates/rss/product/price.phtml
index ef9c29e5e049a7820400e382af3162e082239619..8624390034aabb601203c0f92f035a75b5d64a58 100644
--- a/app/code/Magento/GroupedProduct/view/frontend/templates/rss/product/price.phtml
+++ b/app/code/Magento/GroupedProduct/view/frontend/templates/rss/product/price.phtml
@@ -32,10 +32,10 @@ $_product = $this->getProduct();
 $_id = $_product->getId();
 $_minimalPriceValue = $_product->getMinimalPrice();
 
-/** @var \Magento\Catalog\Helper\Product\Price $priceHelper */
-$priceHelper = $this->helper('Magento\Catalog\Helper\Product\Price');
-$_exclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax = null);
-$_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax = true);
+/** @var \Magento\Tax\Helper\Data $taxHelper */
+$taxHelper = $this->helper('Magento\Tax\Helper\Data');
+$_exclTax = $taxHelper->getPrice($_product, $_minimalPriceValue, $includingTax = null);
+$_inclTax = $taxHelper->getPrice($_product, $_minimalPriceValue, $includingTax = true);
 ?>
 
 <?php if ($_product->getCanShowPrice() !== false):?>
@@ -55,7 +55,7 @@ $_inclTax = $priceHelper->getPrice($_product, $_minimalPriceValue, $includingTax
                 <?php else: ?>
                     <?php
                     $_showPrice = $_inclTax;
-                    if (!$priceHelper->displayPriceIncludingTax()) {
+                    if (!$taxHelper->displayPriceIncludingTax()) {
                         $_showPrice = $_exclTax;
                     }
                     ?>
diff --git a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit.php b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit.php
index 87ecc77628c3534d5c12cb0c945f477e0ce16c9c..1e7ac1dc437d003e15888bd356e3238bafbfe0bb 100644
--- a/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit.php
+++ b/app/code/Magento/ImportExport/Block/Adminhtml/Import/Edit.php
@@ -40,27 +40,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     {
         parent::_construct();
 
-        $this->removeButton(
-            'back'
-        )->removeButton(
-            'reset'
-        )->_updateButton(
-            'save',
-            'label',
-            __('Check Data')
-        )->_updateButton(
-            'save',
-            'id',
-            'upload_button'
-        )->_updateButton(
-            'save',
-            'onclick',
-            'varienImport.postToFrame();'
-        )->_updateButton(
-            'save',
-            'data_attribute',
-            ''
-        );
+        $this->buttonList->remove('back');
+        $this->buttonList->remove('reset');
+        $this->buttonList->update('save', 'label', __('Check Data'));
+        $this->buttonList->update('save', 'id', 'upload_button');
+        $this->buttonList->update('save', 'onclick', 'varienImport.postToFrame();');
+        $this->buttonList->update('save', 'data_attribute', '');
 
         $this->_objectId = 'import_id';
         $this->_blockGroup = 'Magento_ImportExport';
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export.php
index 982fc6dc26dd3f3e6d7cec5c15ca2592b131651d..1afdfc2147f5901df7c739a55ae5e235b316ab21 100644
--- a/app/code/Magento/ImportExport/Controller/Adminhtml/Export.php
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export.php
@@ -31,37 +31,6 @@ namespace Magento\ImportExport\Controller\Adminhtml;
 
 class Export extends \Magento\Backend\App\Action
 {
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-    ) {
-        $this->_fileFactory = $fileFactory;
-        parent::__construct($context);
-    }
-
-    /**
-     * Initialize layout.
-     *
-     * @return $this
-     */
-    protected function _initAction()
-    {
-        $this->_title->add(__('Import/Export'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_ImportExport::system_convert_export');
-
-        return $this;
-    }
-
     /**
      * Check access (in the ACL) for current user
      *
@@ -71,81 +40,4 @@ class Export extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_ImportExport::export');
     }
-
-    /**
-     * Load data with filter applying and create file for download.
-     *
-     * @return $this
-     */
-    public function exportAction()
-    {
-        if ($this->getRequest()->getPost(\Magento\ImportExport\Model\Export::FILTER_ELEMENT_GROUP)) {
-            try {
-                /** @var $model \Magento\ImportExport\Model\Export */
-                $model = $this->_objectManager->create('Magento\ImportExport\Model\Export');
-                $model->setData($this->getRequest()->getParams());
-
-                return $this->_fileFactory->create(
-                    $model->getFileName(),
-                    $model->export(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    $model->getContentType()
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError(__('Please correct the data sent.'));
-            }
-        } else {
-            $this->messageManager->addError(__('Please correct the data sent.'));
-        }
-        return $this->_redirect('adminhtml/*/index');
-    }
-
-    /**
-     * Index action.
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_initAction();
-        $this->_title->add(__('Export'));
-        $this->_addBreadcrumb(__('Export'), __('Export'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Get grid-filter of entity attributes action.
-     *
-     * @return void
-     */
-    public function getFilterAction()
-    {
-        $data = $this->getRequest()->getParams();
-        if ($this->getRequest()->isXmlHttpRequest() && $data) {
-            try {
-                $this->_view->loadLayout();
-
-                /** @var $attrFilterBlock \Magento\ImportExport\Block\Adminhtml\Export\Filter */
-                $attrFilterBlock = $this->_view->getLayout()->getBlock('export.filter');
-                /** @var $export \Magento\ImportExport\Model\Export */
-                $export = $this->_objectManager->create('Magento\ImportExport\Model\Export');
-                $export->setData($data);
-
-                $export->filterAttributeCollection(
-                    $attrFilterBlock->prepareCollection($export->getEntityAttributeCollection())
-                );
-                $this->_view->renderLayout();
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        } else {
-            $this->messageManager->addError(__('Please correct the data sent.'));
-        }
-        $this->_redirect('adminhtml/*/index');
-    }
 }
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6bc35cf35df2b08c03ee9c2127a2e48d0a5a8b9
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Export.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Export;
+
+class Export extends \Magento\ImportExport\Controller\Adminhtml\Export
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * Load data with filter applying and create file for download.
+     *
+     * @return $this
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getPost(\Magento\ImportExport\Model\Export::FILTER_ELEMENT_GROUP)) {
+            try {
+                /** @var $model \Magento\ImportExport\Model\Export */
+                $model = $this->_objectManager->create('Magento\ImportExport\Model\Export');
+                $model->setData($this->getRequest()->getParams());
+
+                return $this->_fileFactory->create(
+                    $model->getFileName(),
+                    $model->export(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    $model->getContentType()
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError(__('Please correct the data sent.'));
+            }
+        } else {
+            $this->messageManager->addError(__('Please correct the data sent.'));
+        }
+        return $this->_redirect('adminhtml/*/index');
+    }
+}
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/GetFilter.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/GetFilter.php
new file mode 100644
index 0000000000000000000000000000000000000000..95cfae2289e4319fd344b9b9bb9337560280607c
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/GetFilter.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Export;
+
+class GetFilter extends \Magento\ImportExport\Controller\Adminhtml\Export
+{
+    /**
+     * Get grid-filter of entity attributes action.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getParams();
+        if ($this->getRequest()->isXmlHttpRequest() && $data) {
+            try {
+                $this->_view->loadLayout();
+
+                /** @var $attrFilterBlock \Magento\ImportExport\Block\Adminhtml\Export\Filter */
+                $attrFilterBlock = $this->_view->getLayout()->getBlock('export.filter');
+                /** @var $export \Magento\ImportExport\Model\Export */
+                $export = $this->_objectManager->create('Magento\ImportExport\Model\Export');
+                $export->setData($data);
+
+                $export->filterAttributeCollection(
+                    $attrFilterBlock->prepareCollection($export->getEntityAttributeCollection())
+                );
+                $this->_view->renderLayout();
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        } else {
+            $this->messageManager->addError(__('Please correct the data sent.'));
+        }
+        $this->_redirect('adminhtml/*/index');
+    }
+}
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Index.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..439c52ccb621e16c49701294338fa27fb7a0bd3f
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Export/Index.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Export;
+
+class Index extends \Magento\ImportExport\Controller\Adminhtml\Export
+{
+    /**
+     * Index action.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Import/Export'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_ImportExport::system_convert_export');
+        $this->_title->add(__('Export'));
+        $this->_addBreadcrumb(__('Export'), __('Export'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import.php
index 5ade5c79e4542550e402a6c0bcc577ee44be2015..2213a124ce25eea74a039396f7deb56c74921969 100644
--- a/app/code/Magento/ImportExport/Controller/Adminhtml/Import.php
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import.php
@@ -30,27 +30,6 @@ namespace Magento\ImportExport\Controller\Adminhtml;
  */
 class Import extends \Magento\Backend\App\Action
 {
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context)
-    {
-        parent::__construct($context);
-    }
-
-    /**
-     * Initialize layout.
-     *
-     * @return $this
-     */
-    protected function _initAction()
-    {
-        $this->_title->add(__('Import/Export'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_ImportExport::system_convert_import');
-        return $this;
-    }
-
     /**
      * Check access (in the ACL) for current user.
      *
@@ -60,179 +39,4 @@ class Import extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_ImportExport::import');
     }
-
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->messageManager->addNotice(
-            $this->_objectManager->get('Magento\ImportExport\Helper\Data')->getMaxUploadSizeMessage()
-        );
-        $this->_initAction();
-        $this->_title->add(__('Import'));
-        $this->_addBreadcrumb(__('Import'), __('Import'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Start import process action
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $this->_view->loadLayout(false);
-
-            /** @var $resultBlock \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result */
-            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
-            /** @var $importModel \Magento\ImportExport\Model\Import */
-            $importModel = $this->_objectManager->create('Magento\ImportExport\Model\Import');
-
-            try {
-                $importModel->importSource();
-                $importModel->invalidateIndex();
-                $resultBlock->addAction(
-                    'show',
-                    'import_validation_container'
-                )->addAction(
-                    'innerHTML',
-                    'import_validation_container_header',
-                    __('Status')
-                );
-            } catch (\Exception $e) {
-                $resultBlock->addError($e->getMessage());
-                $this->_view->renderLayout();
-                return;
-            }
-            $resultBlock->addAction(
-                'hide',
-                array('edit_form', 'upload_button', 'messages')
-            )->addSuccess(
-                __('Import successfully done')
-            );
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('adminhtml/*/index');
-        }
-    }
-
-    /**
-     * Validate uploaded files action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $this->_view->loadLayout(false);
-            /** @var $resultBlock \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result */
-            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
-            // common actions
-            $resultBlock->addAction(
-                'show',
-                'import_validation_container'
-            )->addAction(
-                'clear',
-                array(
-                    \Magento\ImportExport\Model\Import::FIELD_NAME_SOURCE_FILE,
-                    \Magento\ImportExport\Model\Import::FIELD_NAME_IMG_ARCHIVE_FILE
-                )
-            );
-
-            try {
-                /** @var $import \Magento\ImportExport\Model\Import */
-                $import = $this->_objectManager->create('Magento\ImportExport\Model\Import')->setData($data);
-                $source = \Magento\ImportExport\Model\Import\Adapter::findAdapterFor(
-                    $import->uploadSource(),
-                    $this->_objectManager->create(
-                        'Magento\Framework\App\Filesystem'
-                    )->getDirectoryWrite(
-                        \Magento\Framework\App\Filesystem::ROOT_DIR
-                    )
-                );
-                $validationResult = $import->validateSource($source);
-
-                if (!$import->getProcessedRowsCount()) {
-                    $resultBlock->addError(__('File does not contain data. Please upload another one'));
-                } else {
-                    if (!$validationResult) {
-                        $this->_processValidationError($import, $resultBlock);
-                    } else {
-                        if ($import->isImportAllowed()) {
-                            $resultBlock->addSuccess(
-                                __('File is valid! To start import process press "Import" button'),
-                                true
-                            );
-                        } else {
-                            $resultBlock->addError(__('File is valid, but import is not possible'), false);
-                        }
-                    }
-                    $resultBlock->addNotice($import->getNotices());
-                    $resultBlock->addNotice(
-                        __(
-                            'Checked rows: %1, checked entities: %2, invalid rows: %3, total errors: %4',
-                            $import->getProcessedRowsCount(),
-                            $import->getProcessedEntitiesCount(),
-                            $import->getInvalidRowsCount(),
-                            $import->getErrorsCount()
-                        )
-                    );
-                }
-            } catch (\Exception $e) {
-                $resultBlock->addNotice(__('Please fix errors and re-upload file.'))->addError($e->getMessage());
-            }
-            $this->_view->renderLayout();
-        } elseif ($this->getRequest()->isPost() && empty($_FILES)) {
-            $this->_view->loadLayout(false);
-            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
-            $resultBlock->addError(__('File was not uploaded'));
-            $this->_view->renderLayout();
-        } else {
-            $this->messageManager->addError(__('Data is invalid or file is not uploaded'));
-            $this->_redirect('adminhtml/*/index');
-        }
-    }
-
-    /**
-     * Process validation results
-     *
-     * @param \Magento\ImportExport\Model\Import $import
-     * @param \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result $resultBlock
-     * @return void
-     */
-    protected function _processValidationError(
-        \Magento\ImportExport\Model\Import $import,
-        \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result $resultBlock
-    ) {
-        if ($import->getProcessedRowsCount() == $import->getInvalidRowsCount()) {
-            $resultBlock->addNotice(__('File is totally invalid. Please fix errors and re-upload file.'));
-        } elseif ($import->getErrorsCount() >= $import->getErrorsLimit()) {
-            $resultBlock->addNotice(
-                __('Errors limit (%1) reached. Please fix errors and re-upload file.', $import->getErrorsLimit())
-            );
-        } else {
-            if ($import->isImportAllowed()) {
-                $resultBlock->addNotice(
-                    __(
-                        'Please fix errors and re-upload file or simply press "Import" button' .
-                        ' to skip rows with errors'
-                    ),
-                    true
-                );
-            } else {
-                $resultBlock->addNotice(__('File is partially valid, but import is not possible'), false);
-            }
-        }
-        // errors info
-        foreach ($import->getErrors() as $errorCode => $rows) {
-            $error = $errorCode . ' ' . __('in rows:') . ' ' . implode(', ', $rows);
-            $resultBlock->addError($error);
-        }
-    }
 }
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Index.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..740ad6748ebbf6b1283804fc731fd10da0784499
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Index.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Import;
+
+class Index extends \Magento\ImportExport\Controller\Adminhtml\Import
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->messageManager->addNotice(
+            $this->_objectManager->get('Magento\ImportExport\Helper\Data')->getMaxUploadSizeMessage()
+        );
+        $this->_title->add(__('Import/Export'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_ImportExport::system_convert_import');
+        $this->_title->add(__('Import'));
+        $this->_addBreadcrumb(__('Import'), __('Import'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..41ca479c007055a43789b810a4dc0601470818f8
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Start.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Import;
+
+class Start extends \Magento\ImportExport\Controller\Adminhtml\Import
+{
+    /**
+     * Start import process action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $this->_view->loadLayout(false);
+
+            /** @var $resultBlock \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result */
+            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
+            /** @var $importModel \Magento\ImportExport\Model\Import */
+            $importModel = $this->_objectManager->create('Magento\ImportExport\Model\Import');
+
+            try {
+                $importModel->importSource();
+                $importModel->invalidateIndex();
+                $resultBlock->addAction(
+                    'show',
+                    'import_validation_container'
+                )->addAction(
+                    'innerHTML',
+                    'import_validation_container_header',
+                    __('Status')
+                );
+            } catch (\Exception $e) {
+                $resultBlock->addError($e->getMessage());
+                $this->_view->renderLayout();
+                return;
+            }
+            $resultBlock->addAction(
+                'hide',
+                array('edit_form', 'upload_button', 'messages')
+            )->addSuccess(
+                __('Import successfully done')
+            );
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('adminhtml/*/index');
+        }
+    }
+}
diff --git a/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e8f33681f4a808f5e33e59f94451821f8ca39e5
--- /dev/null
+++ b/app/code/Magento/ImportExport/Controller/Adminhtml/Import/Validate.php
@@ -0,0 +1,143 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ImportExport\Controller\Adminhtml\Import;
+
+class Validate extends \Magento\ImportExport\Controller\Adminhtml\Import
+{
+    /**
+     * Process validation results
+     *
+     * @param \Magento\ImportExport\Model\Import $import
+     * @param \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result $resultBlock
+     * @return void
+     */
+    protected function _processValidationError(
+        \Magento\ImportExport\Model\Import $import,
+        \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result $resultBlock
+    ) {
+        if ($import->getProcessedRowsCount() == $import->getInvalidRowsCount()) {
+            $resultBlock->addNotice(__('File is totally invalid. Please fix errors and re-upload file.'));
+        } elseif ($import->getErrorsCount() >= $import->getErrorsLimit()) {
+            $resultBlock->addNotice(
+                __('Errors limit (%1) reached. Please fix errors and re-upload file.', $import->getErrorsLimit())
+            );
+        } else {
+            if ($import->isImportAllowed()) {
+                $resultBlock->addNotice(
+                    __(
+                        'Please fix errors and re-upload file or simply press "Import" button' .
+                        ' to skip rows with errors'
+                    ),
+                    true
+                );
+            } else {
+                $resultBlock->addNotice(__('File is partially valid, but import is not possible'), false);
+            }
+        }
+        // errors info
+        foreach ($import->getErrors() as $errorCode => $rows) {
+            $error = $errorCode . ' ' . __('in rows:') . ' ' . implode(', ', $rows);
+            $resultBlock->addError($error);
+        }
+    }
+
+    /**
+     * Validate uploaded files action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $this->_view->loadLayout(false);
+            /** @var $resultBlock \Magento\ImportExport\Block\Adminhtml\Import\Frame\Result */
+            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
+            // common actions
+            $resultBlock->addAction(
+                'show',
+                'import_validation_container'
+            )->addAction(
+                'clear',
+                array(
+                    \Magento\ImportExport\Model\Import::FIELD_NAME_SOURCE_FILE,
+                    \Magento\ImportExport\Model\Import::FIELD_NAME_IMG_ARCHIVE_FILE
+                )
+            );
+
+            try {
+                /** @var $import \Magento\ImportExport\Model\Import */
+                $import = $this->_objectManager->create('Magento\ImportExport\Model\Import')->setData($data);
+                $source = \Magento\ImportExport\Model\Import\Adapter::findAdapterFor(
+                    $import->uploadSource(),
+                    $this->_objectManager->create(
+                        'Magento\Framework\App\Filesystem'
+                    )->getDirectoryWrite(
+                        \Magento\Framework\App\Filesystem::ROOT_DIR
+                    )
+                );
+                $validationResult = $import->validateSource($source);
+
+                if (!$import->getProcessedRowsCount()) {
+                    $resultBlock->addError(__('File does not contain data. Please upload another one'));
+                } else {
+                    if (!$validationResult) {
+                        $this->_processValidationError($import, $resultBlock);
+                    } else {
+                        if ($import->isImportAllowed()) {
+                            $resultBlock->addSuccess(
+                                __('File is valid! To start import process press "Import" button'),
+                                true
+                            );
+                        } else {
+                            $resultBlock->addError(__('File is valid, but import is not possible'), false);
+                        }
+                    }
+                    $resultBlock->addNotice($import->getNotices());
+                    $resultBlock->addNotice(
+                        __(
+                            'Checked rows: %1, checked entities: %2, invalid rows: %3, total errors: %4',
+                            $import->getProcessedRowsCount(),
+                            $import->getProcessedEntitiesCount(),
+                            $import->getInvalidRowsCount(),
+                            $import->getErrorsCount()
+                        )
+                    );
+                }
+            } catch (\Exception $e) {
+                $resultBlock->addNotice(__('Please fix errors and re-upload file.'))->addError($e->getMessage());
+            }
+            $this->_view->renderLayout();
+        } elseif ($this->getRequest()->isPost() && empty($_FILES)) {
+            $this->_view->loadLayout(false);
+            $resultBlock = $this->_view->getLayout()->getBlock('import.frame.result');
+            $resultBlock->addError(__('File was not uploaded'));
+            $this->_view->renderLayout();
+        } else {
+            $this->messageManager->addError(__('Data is invalid or file is not uploaded'));
+            $this->_redirect('adminhtml/*/index');
+        }
+    }
+}
diff --git a/app/code/Magento/ImportExport/Helper/Data.php b/app/code/Magento/ImportExport/Helper/Data.php
index e5c8acd37f59e28aacabc7ecbbeb0737006a06f6..2fab16f07a581a0fa4e50ad901b97f58219b32cb 100644
--- a/app/code/Magento/ImportExport/Helper/Data.php
+++ b/app/code/Magento/ImportExport/Helper/Data.php
@@ -82,7 +82,7 @@ class Data extends \Magento\Core\Helper\Data
     {
         $maxImageSize = $this->_fileSize->getMaxFileSizeInMb();
         if ($maxImageSize) {
-            $message = __('The total size of the uploadable files can\'t be more that %1M', $maxImageSize);
+            $message = __('The total size of the uploadable files can\'t be more than %1M', $maxImageSize);
         } else {
             $message = __('System doesn\'t allow to get file upload settings');
         }
diff --git a/app/code/Magento/ImportExport/i18n/de_DE.csv b/app/code/Magento/ImportExport/i18n/de_DE.csv
index 9ba56e2886c09d8425d83a37a3775758556a3559..461247982b4b1e8019e18cb7a6dd49bb76222568 100644
--- a/app/code/Magento/ImportExport/i18n/de_DE.csv
+++ b/app/code/Magento/ImportExport/i18n/de_DE.csv
@@ -35,7 +35,7 @@ Import/Export,Import/Export
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","Datei ist teilweise gültig, Import ist aber nicht möglich"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/en_US.csv b/app/code/Magento/ImportExport/i18n/en_US.csv
index 05144e02a98a515ee28c59cdd8c378329f9be66b..e30360177816976b7747ee3761c3aad87a1d1b3a 100644
--- a/app/code/Magento/ImportExport/i18n/en_US.csv
+++ b/app/code/Magento/ImportExport/i18n/en_US.csv
@@ -35,7 +35,7 @@ Import/Export,Import/Export
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","File is partially valid, but import is not possible"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/es_ES.csv b/app/code/Magento/ImportExport/i18n/es_ES.csv
index 44213bbe9247821092a1a0dae716a12edd626315..17ea3c0d24ab67eefce3ca594e11c9b04908b44d 100644
--- a/app/code/Magento/ImportExport/i18n/es_ES.csv
+++ b/app/code/Magento/ImportExport/i18n/es_ES.csv
@@ -35,7 +35,7 @@ Import/Export,Importar/Exportar
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","El archivo es parcialmente válido, pero no es posible importar"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/fr_FR.csv b/app/code/Magento/ImportExport/i18n/fr_FR.csv
index 334869e29ffa7ef88ae20aed896be2607f409d9d..d23749c9eea903b478bc3956b6d93c655bb80f9b 100644
--- a/app/code/Magento/ImportExport/i18n/fr_FR.csv
+++ b/app/code/Magento/ImportExport/i18n/fr_FR.csv
@@ -35,7 +35,7 @@ Import/Export,"Importer / Exporter"
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","Le fichier est partiellement valide, mais l'importation est impossible"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/nl_NL.csv b/app/code/Magento/ImportExport/i18n/nl_NL.csv
index fc27f6d637104da9b3bc5caf883e43fd78eebf4e..9c4ea12ab2505a50e2633e6fed66c776fa51a0f3 100644
--- a/app/code/Magento/ImportExport/i18n/nl_NL.csv
+++ b/app/code/Magento/ImportExport/i18n/nl_NL.csv
@@ -35,7 +35,7 @@ Import/Export,Import/Export
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","Bestand is gedeeltelijk geldig, maar het is niet mogelijk te importeren"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/pt_BR.csv b/app/code/Magento/ImportExport/i18n/pt_BR.csv
index 1d03b6c8a1d112bc1ebbf09ee5b3353b5bdc694c..9df23544ea03d2b712e9f69b2c5aac2b09ad39be 100644
--- a/app/code/Magento/ImportExport/i18n/pt_BR.csv
+++ b/app/code/Magento/ImportExport/i18n/pt_BR.csv
@@ -35,7 +35,7 @@ Import/Export,Importação/Exportação
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible","Arquivo é parcialmente válido, mas a importação não é possível"
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/ImportExport/i18n/zh_CN.csv b/app/code/Magento/ImportExport/i18n/zh_CN.csv
index 75fc92958c8f098d857aca1ee0eb7bb3a4d65f91..d477cb317a70b44d03cc11eadd67fcd0aa3dfa60 100644
--- a/app/code/Magento/ImportExport/i18n/zh_CN.csv
+++ b/app/code/Magento/ImportExport/i18n/zh_CN.csv
@@ -35,7 +35,7 @@ Import/Export,导入/导出
 "Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors","Please fix errors and re-upload file or simply press ""Import"" button' ' to skip rows with errors"
 "File is partially valid, but import is not possible",文件部分有效,但无法导入
 "in rows:","in rows:"
-"The total size of the uploadable files can't be more that %1M","The total size of the uploadable files can't be more that %1M"
+"The total size of the uploadable files can't be more than %1M","The total size of the uploadable files can't be more than %1M"
 "System doesn't allow to get file upload settings","System doesn't allow to get file upload settings"
 "Please enter a correct entity model","Please enter a correct entity model"
 "Entity adapter object must be an instance of %1 or %2","Entity adapter object must be an instance of %1 or %2"
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process.php b/app/code/Magento/Index/Block/Adminhtml/Process.php
index f4d094f411734cb16b3a2ee4da149cedc7d6183f..0b69d2f65632e6d04afe9f1a785a5e4c39a387da 100644
--- a/app/code/Magento/Index/Block/Adminhtml/Process.php
+++ b/app/code/Magento/Index/Block/Adminhtml/Process.php
@@ -34,6 +34,6 @@ class Process extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_process';
         $this->_headerText = __('Index Management');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php b/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
index 0de36256d45a3254c3ba6ffcbc4a31e322fecb58..959dc8a818a3994e301c0d6aba8719400970bd8b 100644
--- a/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
+++ b/app/code/Magento/Index/Block/Adminhtml/Process/Edit.php
@@ -33,12 +33,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -57,15 +57,15 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Process'));
+        $this->buttonList->update('save', 'label', __('Save Process'));
         if ($this->_coreRegistry->registry('current_index_process')) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'reindex',
                 array('label' => __('Reindex Data'), 'onclick' => "setLocation('{$this->getRunUrl()}')")
             );
         }
-        $this->_removeButton('reset');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process.php b/app/code/Magento/Index/Controller/Adminhtml/Process.php
index c3b00af6e0dfa265f949f30cbc42c5dce86f65e6..28b247780f7d06f75a645b1651a3273ece2bcb4d 100644
--- a/app/code/Magento/Index/Controller/Adminhtml/Process.php
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process.php
@@ -80,185 +80,6 @@ class Process extends \Magento\Backend\App\Action
         return false;
     }
 
-    /**
-     * Display processes grid action
-     *
-     * @return void
-     */
-    public function listAction()
-    {
-        $this->_title->add(__('Index Management'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Index::system_index');
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Index\Block\Adminhtml\Process'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Process detail and edit action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            $this->_title->add($process->getIndexCode());
-            $this->_title->add(__('System'));
-            $this->_title->add(__('Index Management'));
-            $this->_title->add(__($process->getIndexer()->getName()));
-
-            $this->_coreRegistry->register('current_index_process', $process);
-            $this->_view->loadLayout();
-            $this->_view->renderLayout();
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-            $this->_redirect('adminhtml/*/list');
-        }
-    }
-
-    /**
-     * Save process data
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            $mode = $this->getRequest()->getPost('mode');
-            if ($mode) {
-                $process->setMode($mode);
-            }
-            try {
-                $process->save();
-                $this->messageManager->addSuccess(__('The index has been saved.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('There was a problem with saving process.'));
-            }
-            $this->_redirect('adminhtml/*/list');
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-            $this->_redirect('adminhtml/*/list');
-        }
-    }
-
-    /**
-     * Reindex all data what process is responsible
-     *
-     * @return void
-     */
-    public function reindexProcessAction()
-    {
-        /** @var $process \Magento\Index\Model\Process */
-        $process = $this->_initProcess();
-        if ($process) {
-            try {
-                \Magento\Framework\Profiler::start('__INDEX_PROCESS_REINDEX_ALL__');
-
-                $process->reindexEverything();
-                \Magento\Framework\Profiler::stop('__INDEX_PROCESS_REINDEX_ALL__');
-                $this->messageManager->addSuccess(__('%1 index was rebuilt.', $process->getIndexer()->getName()));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('There was a problem with reindexing process.'));
-            }
-        } else {
-            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-
-    /**
-     * Reindex pending events for index process
-     *
-     * @return void
-     */
-    public function reindexEventsAction()
-    {
-    }
-
-    /**
-     * Rebiuld all processes index
-     *
-     * @return void
-     */
-    public function reindexAllAction()
-    {
-    }
-
-    /**
-     * Mass rebuild selected processes index
-     *
-     * @return void
-     */
-    public function massReindexAction()
-    {
-        $processIds = $this->getRequest()->getParam('process');
-        if (empty($processIds) || !is_array($processIds)) {
-            $this->messageManager->addError(__('Please select Indexes'));
-        } else {
-            try {
-                $counter = 0;
-                foreach ($processIds as $processId) {
-                    /* @var $process \Magento\Index\Model\Process */
-                    $process = $this->_indexer->getProcessById($processId);
-                    if ($process && $process->getIndexer()->isVisible()) {
-                        $process->reindexEverything();
-                        $counter++;
-                    }
-                }
-                $this->messageManager->addSuccess(__('Total of %1 index(es) have reindexed data.', $counter));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
-            }
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-
-    /**
-     * Mass change index mode of selected processes index
-     *
-     * @return void
-     */
-    public function massChangeModeAction()
-    {
-        $processIds = $this->getRequest()->getParam('process');
-        if (empty($processIds) || !is_array($processIds)) {
-            $this->messageManager->addError(__('Please select Index(es)'));
-        } else {
-            try {
-                $counter = 0;
-                $mode = $this->getRequest()->getParam('index_mode');
-                foreach ($processIds as $processId) {
-                    /* @var $process \Magento\Index\Model\Process */
-                    $process = $this->_processFactory->create()->load($processId);
-                    if ($process->getId() && $process->getIndexer()->isVisible()) {
-                        $process->setMode($mode)->save();
-                        $counter++;
-                    }
-                }
-                $this->messageManager->addSuccess(__('Total of %1 index(es) have changed index mode.', $counter));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
-            }
-        }
-
-        $this->_redirect('adminhtml/*/list');
-    }
-
     /**
      * Check ACL permissins
      *
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php b/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..3cd62ad572204983a76f3a50f6ca860bceb8ad5c
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/Edit.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class Edit extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Process detail and edit action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $process \Magento\Index\Model\Process */
+        $process = $this->_initProcess();
+        if ($process) {
+            $this->_title->add($process->getIndexCode());
+            $this->_title->add(__('System'));
+            $this->_title->add(__('Index Management'));
+            $this->_title->add(__($process->getIndexer()->getName()));
+
+            $this->_coreRegistry->register('current_index_process', $process);
+            $this->_view->loadLayout();
+            $this->_view->renderLayout();
+        } else {
+            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
+            $this->_redirect('adminhtml/*/list');
+        }
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php b/app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..b03a433d44c229f5bac23ebcad62f530e0fd6c65
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/ListAction.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class ListAction extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Display processes grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Index Management'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Index::system_index');
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Index\Block\Adminhtml\Process'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php b/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5b05b84b50f6ee62c745397a113a6fd4df35b00
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/MassChangeMode.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class MassChangeMode extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Mass change index mode of selected processes index
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $processIds = $this->getRequest()->getParam('process');
+        if (empty($processIds) || !is_array($processIds)) {
+            $this->messageManager->addError(__('Please select Index(es)'));
+        } else {
+            try {
+                $counter = 0;
+                $mode = $this->getRequest()->getParam('index_mode');
+                foreach ($processIds as $processId) {
+                    /* @var $process \Magento\Index\Model\Process */
+                    $process = $this->_processFactory->create()->load($processId);
+                    if ($process->getId() && $process->getIndexer()->isVisible()) {
+                        $process->setMode($mode)->save();
+                        $counter++;
+                    }
+                }
+                $this->messageManager->addSuccess(__('Total of %1 index(es) have changed index mode.', $counter));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
+            }
+        }
+
+        $this->_redirect('adminhtml/*/list');
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php b/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php
new file mode 100644
index 0000000000000000000000000000000000000000..175642f82fa3d56a22411eaea617299573f34eef
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/MassReindex.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class MassReindex extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Mass rebuild selected processes index
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $processIds = $this->getRequest()->getParam('process');
+        if (empty($processIds) || !is_array($processIds)) {
+            $this->messageManager->addError(__('Please select Indexes'));
+        } else {
+            try {
+                $counter = 0;
+                foreach ($processIds as $processId) {
+                    /* @var $process \Magento\Index\Model\Process */
+                    $process = $this->_indexer->getProcessById($processId);
+                    if ($process && $process->getIndexer()->isVisible()) {
+                        $process->reindexEverything();
+                        $counter++;
+                    }
+                }
+                $this->messageManager->addSuccess(__('Total of %1 index(es) have reindexed data.', $counter));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Cannot initialize the indexer process.'));
+            }
+        }
+
+        $this->_redirect('adminhtml/*/list');
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php
new file mode 100644
index 0000000000000000000000000000000000000000..f11a90a801dadaef9bc44a5de2a72ce12530b0b4
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexAll.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class ReindexAll extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Rebiuld all processes index
+     *
+     * @return void
+     */
+    public function execute()
+    {
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c8fd557897dd2b643d192be106d241c9dc9e766
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexEvents.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class ReindexEvents extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Reindex pending events for index process
+     *
+     * @return void
+     */
+    public function execute()
+    {
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php
new file mode 100644
index 0000000000000000000000000000000000000000..9cd0b6df8f722c6143dd0b8a4b3c32037da04f96
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/ReindexProcess.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class ReindexProcess extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Reindex all data what process is responsible
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $process \Magento\Index\Model\Process */
+        $process = $this->_initProcess();
+        if ($process) {
+            try {
+                \Magento\Framework\Profiler::start('__INDEX_PROCESS_REINDEX_ALL__');
+
+                $process->reindexEverything();
+                \Magento\Framework\Profiler::stop('__INDEX_PROCESS_REINDEX_ALL__');
+                $this->messageManager->addSuccess(__('%1 index was rebuilt.', $process->getIndexer()->getName()));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('There was a problem with reindexing process.'));
+            }
+        } else {
+            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
+        }
+
+        $this->_redirect('adminhtml/*/list');
+    }
+}
diff --git a/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php b/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..af69f23f74f2e824a1f9c13f88b45acd915c507f
--- /dev/null
+++ b/app/code/Magento/Index/Controller/Adminhtml/Process/Save.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Index\Controller\Adminhtml\Process;
+
+class Save extends \Magento\Index\Controller\Adminhtml\Process
+{
+    /**
+     * Save process data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $process \Magento\Index\Model\Process */
+        $process = $this->_initProcess();
+        if ($process) {
+            $mode = $this->getRequest()->getPost('mode');
+            if ($mode) {
+                $process->setMode($mode);
+            }
+            try {
+                $process->save();
+                $this->messageManager->addSuccess(__('The index has been saved.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('There was a problem with saving process.'));
+            }
+            $this->_redirect('adminhtml/*/list');
+        } else {
+            $this->messageManager->addError(__('Cannot initialize the indexer process.'));
+            $this->_redirect('adminhtml/*/list');
+        }
+    }
+}
diff --git a/app/code/Magento/Indexer/Block/Backend/Container.php b/app/code/Magento/Indexer/Block/Backend/Container.php
index 6612eeeaeec87b2fa5f3c7b3d84eb4ca391a5451..11c7cdcaaa6f3804e51860f6cca126cc4afdb476 100644
--- a/app/code/Magento/Indexer/Block/Backend/Container.php
+++ b/app/code/Magento/Indexer/Block/Backend/Container.php
@@ -36,6 +36,6 @@ class Container extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Indexer';
         $this->_headerText = __('New Indexer Management');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer.php b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer.php
index 276393c53401cf3786aa58a0a1d7316846d95303..270f06092c4aae0c7b0c84df76139cb7aa7d7ec5 100644
--- a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer.php
+++ b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer.php
@@ -25,91 +25,6 @@ namespace Magento\Indexer\Controller\Adminhtml;
 
 class Indexer extends \Magento\Backend\App\Action
 {
-    /**
-     * Display processes grid action
-     *
-     * @return void
-     */
-    public function listAction()
-    {
-        $this->_title->add(__('New Index Management'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Indexer::system_index');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Turn mview off for the given indexers
-     *
-     * @return void
-     */
-    public function massOnTheFlyAction()
-    {
-        $indexerIds = $this->getRequest()->getParam('indexer_ids');
-        if (!is_array($indexerIds)) {
-            $this->messageManager->addError(__('Please select indexers.'));
-        } else {
-            try {
-                foreach ($indexerIds as $indexer_id) {
-                    /** @var \Magento\Indexer\Model\IndexerInterface $model */
-                    $model = $this->_objectManager->create(
-                        'Magento\Indexer\Model\IndexerInterface'
-                    )->load(
-                        $indexer_id
-                    );
-                    $model->setScheduled(false);
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 indexer(s) have been turned Update on Save mode on.', count($indexerIds))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __("We couldn't change indexer(s)' mode because of an error.")
-                );
-            }
-        }
-        $this->_redirect('*/*/list');
-    }
-
-    /**
-     * Turn mview on for the given indexers
-     *
-     * @return void
-     */
-    public function massChangelogAction()
-    {
-        $indexerIds = $this->getRequest()->getParam('indexer_ids');
-        if (!is_array($indexerIds)) {
-            $this->messageManager->addError(__('Please select indexers.'));
-        } else {
-            try {
-                foreach ($indexerIds as $indexer_id) {
-                    /** @var \Magento\Indexer\Model\IndexerInterface $model */
-                    $model = $this->_objectManager->create(
-                        'Magento\Indexer\Model\IndexerInterface'
-                    )->load(
-                        $indexer_id
-                    );
-                    $model->setScheduled(true);
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 indexer(s) have been turned Update by Schedule mode on.', count($indexerIds))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __("We couldn't change indexer(s)' mode because of an error.")
-                );
-            }
-        }
-        $this->_redirect('*/*/list');
-    }
 
     /**
      * Check ACL permissions
diff --git a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..51dfdc1ca441f1a9e46d94346c6d2ea5efdf461b
--- /dev/null
+++ b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/ListAction.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Indexer\Controller\Adminhtml\Indexer;
+
+class ListAction extends \Magento\Indexer\Controller\Adminhtml\Indexer
+{
+    /**
+     * Display processes grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('New Index Management'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Indexer::system_index');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassChangelog.php b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassChangelog.php
new file mode 100644
index 0000000000000000000000000000000000000000..979f028918f9cf935aace685ede60527cf59aa5b
--- /dev/null
+++ b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassChangelog.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Indexer\Controller\Adminhtml\Indexer;
+
+class MassChangelog extends \Magento\Indexer\Controller\Adminhtml\Indexer
+{
+    /**
+     * Turn mview on for the given indexers
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $indexerIds = $this->getRequest()->getParam('indexer_ids');
+        if (!is_array($indexerIds)) {
+            $this->messageManager->addError(__('Please select indexers.'));
+        } else {
+            try {
+                foreach ($indexerIds as $indexer_id) {
+                    /** @var \Magento\Indexer\Model\IndexerInterface $model */
+                    $model = $this->_objectManager->create(
+                        'Magento\Indexer\Model\IndexerInterface'
+                    )->load(
+                        $indexer_id
+                    );
+                    $model->setScheduled(true);
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 indexer(s) have been turned Update by Schedule mode on.', count($indexerIds))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __("We couldn't change indexer(s)' mode because of an error.")
+                );
+            }
+        }
+        $this->_redirect('*/*/list');
+    }
+}
diff --git a/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassOnTheFly.php b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassOnTheFly.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2d6ffd32c0a79c759c82acc1edabf3ca1e53661
--- /dev/null
+++ b/app/code/Magento/Indexer/Controller/Adminhtml/Indexer/MassOnTheFly.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Indexer\Controller\Adminhtml\Indexer;
+
+class MassOnTheFly extends \Magento\Indexer\Controller\Adminhtml\Indexer
+{
+    /**
+     * Turn mview off for the given indexers
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $indexerIds = $this->getRequest()->getParam('indexer_ids');
+        if (!is_array($indexerIds)) {
+            $this->messageManager->addError(__('Please select indexers.'));
+        } else {
+            try {
+                foreach ($indexerIds as $indexer_id) {
+                    /** @var \Magento\Indexer\Model\IndexerInterface $model */
+                    $model = $this->_objectManager->create(
+                        'Magento\Indexer\Model\IndexerInterface'
+                    )->load(
+                        $indexer_id
+                    );
+                    $model->setScheduled(false);
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 indexer(s) have been turned Update on Save mode on.', count($indexerIds))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __("We couldn't change indexer(s)' mode because of an error.")
+                );
+            }
+        }
+        $this->_redirect('*/*/list');
+    }
+}
diff --git a/app/code/Magento/Indexer/Model/Indexer/AbstractProcessor.php b/app/code/Magento/Indexer/Model/Indexer/AbstractProcessor.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddcd840c19a0f838ce4dd807a649d9db9cfcc91d
--- /dev/null
+++ b/app/code/Magento/Indexer/Model/Indexer/AbstractProcessor.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_Indexer
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Indexer\Model\Indexer;
+
+abstract class AbstractProcessor
+{
+    /**
+     * Indexer ID
+     */
+    const INDEXER_ID = '';
+
+    /**
+     * @var \Magento\Indexer\Model\IndexerInterface
+     */
+    protected $_indexer;
+
+    /**
+     * @param \Magento\Indexer\Model\IndexerFactory $indexerFactory
+     */
+    public function __construct(
+        \Magento\Indexer\Model\IndexerFactory $indexerFactory
+    ) {
+        $this->_indexer = $indexerFactory->create();
+    }
+
+    /**
+     * Get indexer
+     *
+     * @return \Magento\Indexer\Model\IndexerInterface
+     */
+    public function getIndexer()
+    {
+        if (!$this->_indexer->getId()) {
+            $this->_indexer->load(static::INDEXER_ID);
+        }
+        return $this->_indexer;
+    }
+
+    /**
+     * Run Row reindex
+     *
+     * @param int $id
+     * @return void
+     */
+    public function reindexRow($id)
+    {
+        if ($this->getIndexer()->isScheduled()) {
+            return;
+        }
+        $this->getIndexer()->reindexRow($id);
+    }
+
+    /**
+     * Run List reindex
+     *
+     * @param int[] $ids
+     * @return void
+     */
+    public function reindexList($ids)
+    {
+        if ($this->getIndexer()->isScheduled()) {
+            return;
+        }
+        $this->getIndexer()->reindexList($ids);
+    }
+
+    /**
+     * Run Full reindex
+     *
+     * @return void
+     */
+    public function reindexAll()
+    {
+        $this->getIndexer()->reindexAll();
+    }
+
+    /**
+     * Mark Product price indexer as invalid
+     *
+     * @return void
+     */
+    public function markIndexerAsInvalid()
+    {
+        $this->getIndexer()->invalidate();
+    }
+}
diff --git a/app/code/Magento/Install/App/Action/Plugin/Design.php b/app/code/Magento/Install/App/Action/Plugin/Design.php
index dc37497236f0783150e91ee0d40ac9505a7d1854..d1b05d3e988d91ab5f47b9fd65838088b01aec89 100644
--- a/app/code/Magento/Install/App/Action/Plugin/Design.php
+++ b/app/code/Magento/Install/App/Action/Plugin/Design.php
@@ -76,13 +76,13 @@ class Design
     /**
      * Initialize design
      *
-     * @param \Magento\Install\Controller\Action $subject
+     * @param \Magento\Framework\App\ActionInterface $subject
      * @param RequestInterface $request
      *
      * @return void
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function beforeDispatch(\Magento\Install\Controller\Action $subject, RequestInterface $request)
+    public function beforeDispatch(\Magento\Framework\App\ActionInterface $subject, RequestInterface $request)
     {
         $areaCode = $this->appState->getAreaCode();
         $area = $this->_areaList->getArea($areaCode);
diff --git a/app/code/Magento/Install/App/Action/Plugin/Dir.php b/app/code/Magento/Install/App/Action/Plugin/Dir.php
index 46c58cf01a3bdb22dbd9dfa1012d103c0917705f..83409bce18c87ff16061a4053b593166444d3a90 100644
--- a/app/code/Magento/Install/App/Action/Plugin/Dir.php
+++ b/app/code/Magento/Install/App/Action/Plugin/Dir.php
@@ -68,14 +68,16 @@ class Dir
     /**
      * Clear temporary directories
      *
-     * @param \Magento\Install\Controller\Index $subject
+     * @param \Magento\Install\Controller\Index\Index $subject
      * @param \Magento\Framework\App\RequestInterface $request
      *
      * @return void
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
-    public function beforeDispatch(\Magento\Install\Controller\Index $subject, \Magento\Framework\App\RequestInterface $request)
-    {
+    public function beforeDispatch(
+        \Magento\Install\Controller\Index\Index $subject,
+        \Magento\Framework\App\RequestInterface $request
+    ) {
         if (!$this->appState->isInstalled()) {
             foreach ($this->varDirectory->read() as $dir) {
                 if ($this->varDirectory->isDirectory($dir)) {
diff --git a/app/code/Magento/Install/Controller/Action.php b/app/code/Magento/Install/Controller/Action.php
deleted file mode 100644
index 31bd44db0094ab7eb9abf2e428ebc99b0ebf4bf2..0000000000000000000000000000000000000000
--- a/app/code/Magento/Install/Controller/Action.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Install\Controller;
-
-class Action extends \Magento\Framework\App\Action\Action
-{
-    /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Framework\Config\Scope $configScope
-     */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Framework\Config\Scope $configScope)
-    {
-        parent::__construct($context);
-        $configScope->setCurrentScope('install');
-    }
-}
diff --git a/app/code/Magento/Install/Controller/Index.php b/app/code/Magento/Install/Controller/Index/Index.php
similarity index 76%
rename from app/code/Magento/Install/Controller/Index.php
rename to app/code/Magento/Install/Controller/Index/Index.php
index 46ac998cc669c59227493be015d2f772c4e2d638..abcb641404528259863c27a38f7deb6fc8656134 100644
--- a/app/code/Magento/Install/Controller/Index.php
+++ b/app/code/Magento/Install/Controller/Index/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,22 +22,20 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Install\Controller\Index;
 
-
-/**
- * Install index controller
- */
-namespace Magento\Install\Controller;
-
-class Index extends \Magento\Install\Controller\Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Framework\Config\Scope $configScope
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Framework\Config\Scope $configScope)
-    {
-        parent::__construct($context, $configScope);
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Config\Scope $configScope
+    ) {
+        parent::__construct($context);
+        $configScope->setCurrentScope('install');
     }
 
     /**
@@ -44,7 +43,7 @@ class Index extends \Magento\Install\Controller\Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $this->_redirect('install/wizard/begin');
     }
diff --git a/app/code/Magento/Install/Controller/Wizard.php b/app/code/Magento/Install/Controller/Wizard.php
index da4992667b28b7be5355ba886aa6406396e5dd91..3957dd78c5d820c5526ac07d5b682d2c5477a2c2 100644
--- a/app/code/Magento/Install/Controller/Wizard.php
+++ b/app/code/Magento/Install/Controller/Wizard.php
@@ -24,12 +24,11 @@
 namespace Magento\Install\Controller;
 
 use Magento\Framework\App\RequestInterface;
-use Magento\Framework\App\ResponseInterface;
 
 /**
  * Installation wizard controller
  */
-class Wizard extends \Magento\Install\Controller\Action
+class Wizard extends \Magento\Framework\App\Action\Action
 {
     /**
      * Application state
@@ -87,7 +86,8 @@ class Wizard extends \Magento\Install\Controller\Action
         \Magento\Framework\App\State $appState
     ) {
         $this->_storeManager = $storeManager;
-        parent::__construct($context, $configScope);
+        parent::__construct($context);
+        $configScope->setCurrentScope('install');
         $this->_installer = $installer;
         $this->_wizard = $wizard;
         $this->_session = $session;
@@ -164,386 +164,4 @@ class Wizard extends \Magento\Install\Controller\Action
         }
         return true;
     }
-
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_redirect('*/*/begin');
-    }
-
-    /**
-     * Begin installation action
-     *
-     * @return void
-     */
-    public function beginAction()
-    {
-        $this->_checkIfInstalled();
-
-        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
-        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\Begin', 'install.begin', 'content');
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Process begin step POST data
-     *
-     * @return void
-     */
-    public function beginPostAction()
-    {
-        $this->_checkIfInstalled();
-
-        $agree = $this->getRequest()->getPost('agree');
-        if ($agree && ($step = $this->_getWizard()->getStepByName('begin'))) {
-            $this->getResponse()->setRedirect($step->getNextUrl());
-        } else {
-            $this->_redirect('install');
-        }
-    }
-
-    /**
-     * Localization settings
-     *
-     * @return void
-     */
-    public function localeAction()
-    {
-        $this->_checkIfInstalled();
-        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
-        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\Locale', 'install.locale', 'content');
-        $this->_view->getLayout()->getBlock('install.locale')->setLocaleCode($this->_session->getLocale());
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Change current locale
-     *
-     * @return void
-     */
-    public function localeChangeAction()
-    {
-        $this->_checkIfInstalled();
-
-        $locale = $this->getRequest()->getParam('locale');
-        $timezone = $this->getRequest()->getParam('timezone');
-        $currency = $this->getRequest()->getParam('currency');
-        if ($locale) {
-            $this->_session->setLocale($locale)->setTimezone($timezone)->setCurrency($currency);
-        }
-
-        $this->_redirect('*/*/locale');
-    }
-
-    /**
-     * Saving localization settings
-     *
-     * @return void
-     */
-    public function localePostAction()
-    {
-        $this->_checkIfInstalled();
-        $step = $this->_getWizard()->getStepByName('locale');
-
-        $data = $this->getRequest()->getPost('config');
-        if ($data) {
-            $this->_session->setLocaleData($data);
-        }
-
-        $this->getResponse()->setRedirect($step->getNextUrl());
-    }
-
-    /**
-     * Download page action
-     *
-     * @return void
-     */
-    public function downloadAction()
-    {
-        $this->_checkIfInstalled();
-        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
-        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\Download', 'install.download', 'content');
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Download post action
-     *
-     * @return void
-     */
-    public function downloadPostAction()
-    {
-        $this->_checkIfInstalled();
-        switch ($this->getRequest()->getPost('continue')) {
-            case 'auto':
-                $this->_forward('downloadAuto');
-                break;
-
-            case 'manual':
-                $this->_forward('downloadManual');
-                break;
-
-            case 'svn':
-                $step = $this->_getWizard()->getStepByName('download');
-                $this->getResponse()->setRedirect($step->getNextUrl());
-                break;
-
-            default:
-                $this->_redirect('*/*/download');
-                break;
-        }
-    }
-
-    /**
-     * Download auto action
-     *
-     * @return void
-     */
-    public function downloadAutoAction()
-    {
-        $step = $this->_getWizard()->getStepByName('download');
-        $this->getResponse()->setRedirect($step->getNextUrl());
-    }
-
-    /**
-     * Install action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.ExitExpression)
-     */
-    public function installAction()
-    {
-        $pear = \Magento\Framework\Pear::getInstance();
-        $params = array('comment' => __("Downloading and installing Magento, please wait...") . "\r\n\r\n");
-        if ($this->getRequest()->getParam('do')) {
-            $state = $this->getRequest()->getParam('state', 'beta');
-            if ($state) {
-                $result = $pear->runHtmlConsole(
-                    array(
-                        'comment' => __("Setting preferred state to: %1", $state) . "\r\n\r\n",
-                        'command' => 'config-set',
-                        'params' => array('preferred_state', $state)
-                    )
-                );
-                if ($result instanceof PEAR_Error) {
-                    $this->installFailureCallback();
-                    exit;
-                }
-            }
-            $params['command'] = 'install';
-            $params['options'] = array('onlyreqdeps' => 1);
-            $params['params'] = $this->_objectManager->get('Magento\Install\Model\Installer\Pear')->getPackages();
-            $params['success_callback'] = array($this, 'installSuccessCallback');
-            $params['failure_callback'] = array($this, 'installFailureCallback');
-        }
-        $pear->runHtmlConsole($params);
-        $this->getResponse()->clearAllHeaders();
-    }
-
-    /**
-     * Install success callback
-     *
-     * @return void
-     */
-    public function installSuccessCallback()
-    {
-        echo 'parent.installSuccess()';
-    }
-
-    /**
-     * Install failure callback
-     *
-     * @return void
-     */
-    public function installFailureCallback()
-    {
-        echo 'parent.installFailure()';
-    }
-
-    /**
-     * Download manual action
-     *
-     * @return void
-     */
-    public function downloadManualAction()
-    {
-        $step = $this->_getWizard()->getStepByName('download');
-        $this->getResponse()->setRedirect($step->getNextUrl());
-    }
-
-    /**
-     * Configuration data installation
-     *
-     * @return void
-     */
-    public function configAction()
-    {
-        $this->_checkIfInstalled();
-        $this->_getInstaller()->checkServer();
-
-        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
-        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
-
-        $data = $this->getRequest()->getQuery('config');
-        if ($data) {
-            $this->_session->setLocaleData($data);
-        }
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\Config', 'install.config', 'content');
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Process configuration POST data
-     *
-     * @return ResponseInterface|void
-     */
-    public function configPostAction()
-    {
-        $this->_checkIfInstalled();
-        $step = $this->_getWizard()->getStepByName('config');
-
-        $config = $this->getRequest()->getPost('config');
-        $connectionConfig = $this->getRequest()->getPost('connection');
-
-        if ($config && $connectionConfig && isset($connectionConfig[$config['db_model']])) {
-
-            $data = array_merge($config, $connectionConfig[$config['db_model']]);
-
-            $this->_session->setConfigData(
-                $data
-            )->setSkipUrlValidation(
-                $this->getRequest()->getPost('skip_url_validation')
-            )->setSkipBaseUrlValidation(
-                $this->getRequest()->getPost('skip_base_url_validation')
-            );
-            try {
-                $this->_getInstaller()->installConfig($data);
-                return $this->_redirect('*/*/installDb');
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->getResponse()->setRedirect($step->getUrl());
-            }
-        }
-        $this->getResponse()->setRedirect($step->getUrl());
-    }
-
-    /**
-     * Install DB
-     *
-     * @return void
-     */
-    public function installDbAction()
-    {
-        $this->_checkIfInstalled();
-        $step = $this->_getWizard()->getStepByName('config');
-        try {
-            $this->_getInstaller()->installDb();
-            /**
-             * Clear session config data
-             */
-            $this->_session->getConfigData(true);
-
-            $this->_storeManager->getStore()->resetConfig();
-            $this->_dbUpdater->updateData();
-
-            $this->getResponse()->setRedirect($step->getNextUrl());
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->getResponse()->setRedirect($step->getUrl());
-        }
-    }
-
-    /**
-     * Install administrator account
-     *
-     * @return void
-     */
-    public function administratorAction()
-    {
-        $this->_checkIfInstalled();
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\Admin', 'install.administrator', 'content');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Process administrator installation POST data
-     *
-     * @return void
-     */
-    public function administratorPostAction()
-    {
-        $this->_checkIfInstalled();
-
-        $step = $this->_wizard->getStepByName('administrator');
-        $adminData = $this->getRequest()->getPost('admin');
-        $encryptionKey = $this->getRequest()->getPost('encryption_key');
-
-        try {
-            $encryptionKey = $this->_getInstaller()->getValidEncryptionKey($encryptionKey);
-            $this->_getInstaller()->createAdministrator($adminData);
-            $this->_getInstaller()->installEncryptionKey($encryptionKey);
-            $this->getResponse()->setRedirect($step->getNextUrl());
-        } catch (\Exception $e) {
-            $this->_session->setAdminData($adminData);
-            if ($e instanceof \Magento\Framework\Model\Exception) {
-                $this->messageManager->addMessages($e->getMessages());
-            } else {
-                $this->messageManager->addError($e->getMessage());
-            }
-            $this->getResponse()->setRedirect($step->getUrl());
-        }
-    }
-
-    /**
-     * End installation
-     *
-     * @return void
-     */
-    public function endAction()
-    {
-        $this->_checkIfInstalled();
-
-        if ($this->_appState->isInstalled()) {
-            $this->_redirect('*/*');
-            return;
-        }
-
-        $this->_getInstaller()->finish();
-
-        $this->_objectManager->get('Magento\AdminNotification\Model\Survey')->saveSurveyViewed(true);
-
-        $this->_prepareLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $this->_view->getLayout()->addBlock('Magento\Install\Block\End', 'install.end', 'content');
-        $this->_view->renderLayout();
-        $this->_session->clearStorage();
-    }
 }
diff --git a/app/code/Magento/Install/Controller/Wizard/Administrator.php b/app/code/Magento/Install/Controller/Wizard/Administrator.php
new file mode 100644
index 0000000000000000000000000000000000000000..ebdd7c395fa99c4a9c1c2ecfcd020a0548dfc3a7
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Administrator.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Administrator extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Install administrator account
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\Admin', 'install.administrator', 'content');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/AdministratorPost.php b/app/code/Magento/Install/Controller/Wizard/AdministratorPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb8054d751bbbf981e92c229e018a579ebe87bc3
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/AdministratorPost.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class AdministratorPost extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Process administrator installation POST data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        $step = $this->_wizard->getStepByName('administrator');
+        $adminData = $this->getRequest()->getPost('admin');
+        $encryptionKey = $this->getRequest()->getPost('encryption_key');
+
+        try {
+            $encryptionKey = $this->_getInstaller()->getValidEncryptionKey($encryptionKey);
+            $this->_getInstaller()->createAdministrator($adminData);
+            $this->_getInstaller()->installEncryptionKey($encryptionKey);
+            $this->getResponse()->setRedirect($step->getNextUrl());
+        } catch (\Exception $e) {
+            $this->_session->setAdminData($adminData);
+            if ($e instanceof \Magento\Framework\Model\Exception) {
+                $this->messageManager->addMessages($e->getMessages());
+            } else {
+                $this->messageManager->addError($e->getMessage());
+            }
+            $this->getResponse()->setRedirect($step->getUrl());
+        }
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Begin.php b/app/code/Magento/Install/Controller/Wizard/Begin.php
new file mode 100644
index 0000000000000000000000000000000000000000..d1a03dad1d700db0e51fc9a8f6f4fae819c6800d
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Begin.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Begin extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Begin installation action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
+        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\Begin', 'install.begin', 'content');
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/BeginPost.php b/app/code/Magento/Install/Controller/Wizard/BeginPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..098c2501a2cf9da768191311c8c23462f0026ba1
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/BeginPost.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class BeginPost extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Process begin step POST data
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        $agree = $this->getRequest()->getPost('agree');
+        if ($agree && ($step = $this->_getWizard()->getStepByName('begin'))) {
+            $this->getResponse()->setRedirect($step->getNextUrl());
+        } else {
+            $this->_redirect('install');
+        }
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Config.php b/app/code/Magento/Install/Controller/Wizard/Config.php
new file mode 100644
index 0000000000000000000000000000000000000000..eed5fe1e447352b9a191d77bcdbd930b028e04b6
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Config.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Config extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Configuration data installation
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $this->_getInstaller()->checkServer();
+
+        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
+        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+
+        $data = $this->getRequest()->getQuery('config');
+        if ($data) {
+            $this->_session->setLocaleData($data);
+        }
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\Config', 'install.config', 'content');
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/ConfigPost.php b/app/code/Magento/Install/Controller/Wizard/ConfigPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..725f4c1ebb68dab11bb31fb8915b7b310b6f9809
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/ConfigPost.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ConfigPost extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Process configuration POST data
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $step = $this->_getWizard()->getStepByName('config');
+
+        $config = $this->getRequest()->getPost('config');
+        $connectionConfig = $this->getRequest()->getPost('connection');
+
+        if ($config && $connectionConfig && isset($connectionConfig[$config['db_model']])) {
+
+            $data = array_merge($config, $connectionConfig[$config['db_model']]);
+
+            $this->_session->setConfigData(
+                $data
+            )->setSkipUrlValidation(
+                $this->getRequest()->getPost('skip_url_validation')
+            )->setSkipBaseUrlValidation(
+                $this->getRequest()->getPost('skip_base_url_validation')
+            );
+            try {
+                $this->_getInstaller()->installConfig($data);
+                return $this->_redirect('*/*/installDb');
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->getResponse()->setRedirect($step->getUrl());
+            }
+        }
+        $this->getResponse()->setRedirect($step->getUrl());
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Download.php b/app/code/Magento/Install/Controller/Wizard/Download.php
new file mode 100644
index 0000000000000000000000000000000000000000..377c77f9600a537599e3a4a8d474b0f272a14359
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Download.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Download extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Download page action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
+        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\Download', 'install.download', 'content');
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/DownloadAuto.php b/app/code/Magento/Install/Controller/Wizard/DownloadAuto.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e178dc7c1a16d681fab8c7c93254f5128070a7c
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/DownloadAuto.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class DownloadAuto extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Download auto action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $step = $this->_getWizard()->getStepByName('download');
+        $this->getResponse()->setRedirect($step->getNextUrl());
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/DownloadManual.php b/app/code/Magento/Install/Controller/Wizard/DownloadManual.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e2d7833ac393d4b6fe224a782235a2f003c11d5
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/DownloadManual.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class DownloadManual extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Download manual action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $step = $this->_getWizard()->getStepByName('download');
+        $this->getResponse()->setRedirect($step->getNextUrl());
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/DownloadPost.php b/app/code/Magento/Install/Controller/Wizard/DownloadPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..794557e3a04e0ae10425dc5c04e4fb0043310368
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/DownloadPost.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class DownloadPost extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Download post action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        switch ($this->getRequest()->getPost('continue')) {
+            case 'auto':
+                $this->_forward('downloadAuto');
+                break;
+
+            case 'manual':
+                $this->_forward('downloadManual');
+                break;
+
+            case 'svn':
+                $step = $this->_getWizard()->getStepByName('download');
+                $this->getResponse()->setRedirect($step->getNextUrl());
+                break;
+
+            default:
+                $this->_redirect('*/*/download');
+                break;
+        }
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/End.php b/app/code/Magento/Install/Controller/Wizard/End.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfd9c13d944c2991cf4ca0eeed4ca49793c7aa0c
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/End.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class End extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * End installation
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        if ($this->_appState->isInstalled()) {
+            $this->_redirect('*/*');
+            return;
+        }
+
+        $this->_getInstaller()->finish();
+
+        $this->_objectManager->get('Magento\AdminNotification\Model\Survey')->saveSurveyViewed(true);
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\End', 'install.end', 'content');
+        $this->_view->renderLayout();
+        $this->_session->clearStorage();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Index.php b/app/code/Magento/Install/Controller/Wizard/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c1bd21c85b7e13c1d6e91bbace312a343ab8ec6
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Index extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_redirect('*/*/begin');
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Install.php b/app/code/Magento/Install/Controller/Wizard/Install.php
new file mode 100644
index 0000000000000000000000000000000000000000..be896613ba68d6a1bf949f706994020fff250a75
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Install.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Install extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Install success callback
+     *
+     * @return void
+     */
+    public function installSuccessCallback()
+    {
+        echo 'parent.installSuccess()';
+    }
+
+    /**
+     * Install failure callback
+     *
+     * @return void
+     */
+    public function installFailureCallback()
+    {
+        echo 'parent.installFailure()';
+    }
+
+    /**
+     * Install action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.ExitExpression)
+     */
+    public function execute()
+    {
+        $pear = \Magento\Framework\Pear::getInstance();
+        $params = array('comment' => __("Downloading and installing Magento, please wait...") . "\r\n\r\n");
+        if ($this->getRequest()->getParam('do')) {
+            $state = $this->getRequest()->getParam('state', 'beta');
+            if ($state) {
+                $result = $pear->runHtmlConsole(
+                    array(
+                        'comment' => __("Setting preferred state to: %1", $state) . "\r\n\r\n",
+                        'command' => 'config-set',
+                        'params' => array('preferred_state', $state)
+                    )
+                );
+                if ($result instanceof PEAR_Error) {
+                    $this->installFailureCallback();
+                    exit;
+                }
+            }
+            $params['command'] = 'install';
+            $params['options'] = array('onlyreqdeps' => 1);
+            $params['params'] = $this->_objectManager->get('Magento\Install\Model\Installer\Pear')->getPackages();
+            $params['success_callback'] = array($this, 'installSuccessCallback');
+            $params['failure_callback'] = array($this, 'installFailureCallback');
+        }
+        $pear->runHtmlConsole($params);
+        $this->getResponse()->clearAllHeaders();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/InstallDb.php b/app/code/Magento/Install/Controller/Wizard/InstallDb.php
new file mode 100644
index 0000000000000000000000000000000000000000..07a7f9fe1761f24f0958388245264b4c168e5e2e
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/InstallDb.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class InstallDb extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Install DB
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $step = $this->_getWizard()->getStepByName('config');
+        try {
+            $this->_getInstaller()->installDb();
+            /**
+             * Clear session config data
+             */
+            $this->_session->getConfigData(true);
+
+            $this->_storeManager->getStore()->resetConfig();
+            $this->_dbUpdater->updateData();
+
+            $this->getResponse()->setRedirect($step->getNextUrl());
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->getResponse()->setRedirect($step->getUrl());
+        }
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/Locale.php b/app/code/Magento/Install/Controller/Wizard/Locale.php
new file mode 100644
index 0000000000000000000000000000000000000000..6cd04ddec47bf294a5e529814a62a040e31b4887
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/Locale.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class Locale extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Localization settings
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $this->_actionFlag->set('', self::FLAG_NO_DISPATCH_BLOCK_EVENT, true);
+        $this->_actionFlag->set('', self::FLAG_NO_POST_DISPATCH, true);
+
+        $this->_prepareLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->getLayout()->addBlock('Magento\Install\Block\Locale', 'install.locale', 'content');
+        $this->_view->getLayout()->getBlock('install.locale')->setLocaleCode($this->_session->getLocale());
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/LocaleChange.php b/app/code/Magento/Install/Controller/Wizard/LocaleChange.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b5428d1dae3c004444f10ce24c21de4172bf61a
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/LocaleChange.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class LocaleChange extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Change current locale
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+
+        $locale = $this->getRequest()->getParam('locale');
+        $timezone = $this->getRequest()->getParam('timezone');
+        $currency = $this->getRequest()->getParam('currency');
+        if ($locale) {
+            $this->_session->setLocale($locale)->setTimezone($timezone)->setCurrency($currency);
+        }
+
+        $this->_redirect('*/*/locale');
+    }
+}
diff --git a/app/code/Magento/Install/Controller/Wizard/LocalePost.php b/app/code/Magento/Install/Controller/Wizard/LocalePost.php
new file mode 100644
index 0000000000000000000000000000000000000000..e98107200f2f5a906b1bb1b316bb35f5c1f47554
--- /dev/null
+++ b/app/code/Magento/Install/Controller/Wizard/LocalePost.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Install\Controller\Wizard;
+
+class LocalePost extends \Magento\Install\Controller\Wizard
+{
+    /**
+     * Saving localization settings
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_checkIfInstalled();
+        $step = $this->_getWizard()->getStepByName('locale');
+
+        $data = $this->getRequest()->getPost('config');
+        if ($data) {
+            $this->_session->setLocaleData($data);
+        }
+
+        $this->getResponse()->setRedirect($step->getNextUrl());
+    }
+}
diff --git a/app/code/Magento/Install/etc/install/di.xml b/app/code/Magento/Install/etc/install/di.xml
index ed15b6d40d8eb99b6f16f89aacc7706f761fb3c4..607cfefdd0805879984a57e3952428795317c25c 100644
--- a/app/code/Magento/Install/etc/install/di.xml
+++ b/app/code/Magento/Install/etc/install/di.xml
@@ -36,11 +36,13 @@
             </argument>
         </arguments>
     </type>
-    <type name="Magento\Install\Controller\Action">
+    <type name="Magento\Install\Controller\Index\Index">
         <plugin name="installInitializer" disabled="true" />
         <plugin name="designLoader" type="Magento\Install\App\Action\Plugin\Design" />
-    </type>
-    <type name="Magento\Install\Controller\Index">
         <plugin name="directoryCleaner" type="Magento\Install\App\Action\Plugin\Dir" sortOrder="10"/>
     </type>
+    <type name="Magento\Install\Controller\Wizard">
+        <plugin name="installInitializer" disabled="true" />
+        <plugin name="designLoader" type="Magento\Install\App\Action\Plugin\Design" />
+    </type>
 </config>
diff --git a/app/code/Magento/Install/view/install/templates/state.phtml b/app/code/Magento/Install/view/install/templates/state.phtml
index 3d81fdf627bb7e5e44780a9ee1463ee930495436..46af94b14591232c416414f132bce1db8461258f 100644
--- a/app/code/Magento/Install/view/install/templates/state.phtml
+++ b/app/code/Magento/Install/view/install/templates/state.phtml
@@ -38,6 +38,6 @@
 <br/>
 <p>
     <?php echo __('Having trouble installing Magento?') ?>
-    <?php echo __('Check out our') ?> <a href="http://www.magentocommerce.com/install"
+    <?php echo __('Check out our') ?> <a href="http://www.magentocommerce.com/magento2/install"
                                                 target="installation_guide"><?php echo __('Installation Guide') ?></a>
 </p>
diff --git a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit.php b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit.php
index 0679cf6640acec75eef63cf7de752e5792bf585f..ed2eac947685de910d19a99402c079383b6d78cb 100644
--- a/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit.php
+++ b/app/code/Magento/Integration/Block/Adminhtml/Integration/Edit.php
@@ -43,13 +43,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     /**
      * Initialize dependencies.
      *
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Integration\Helper\Data $integrationHelper
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Integration\Helper\Data $integrationHelper,
         array $data = array()
@@ -69,14 +69,14 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml_integration';
         $this->_blockGroup = 'Magento_Integration';
         parent::_construct();
-        $this->_removeButton('reset');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
 
         if ($this->_integrationHelper->isConfigType(
             $this->_registry->registry(Integration::REGISTRY_KEY_CURRENT_INTEGRATION)
         )
         ) {
-            $this->_removeButton('save');
+            $this->buttonList->remove('save');
         }
 
         if ($this->_isNewIntegration()) {
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
index 4a34748a8d0b0b330249f5c267314d2003d9705a..913cb6c7697192b039c134b7ec84b1d2a7f18ab7 100644
--- a/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration.php
@@ -24,8 +24,6 @@
 namespace Magento\Integration\Controller\Adminhtml;
 
 use Magento\Backend\App\Action;
-use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
-use Magento\Integration\Exception as IntegrationException;
 use Magento\Integration\Service\V1\OauthInterface as IntegrationOauthService;
 use Magento\Integration\Model\Integration as IntegrationModel;
 
@@ -53,7 +51,7 @@ class Integration extends Action
     protected $_logger;
 
     /** @var \Magento\Integration\Service\V1\IntegrationInterface */
-    private $_integrationService;
+    protected $_integrationService;
 
     /** @var IntegrationOauthService */
     protected $_oauthService;
@@ -106,38 +104,6 @@ class Integration extends Action
         parent::__construct($context);
     }
 
-    /**
-     * Integrations grid.
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $unsecureIntegrationsCount = $this->_integrationCollection->addUnsecureUrlsFilter()->getSize();
-        if ($unsecureIntegrationsCount > 0) {
-            // @codingStandardsIgnoreStart
-            $this->messageManager->addNotice(__('Warning! Integrations not using HTTPS are insecure and potentially expose private or personally identifiable information')
-            // @codingStandardsIgnoreEnd
-            );
-        }
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Integration::system_integrations');
-        $this->_addBreadcrumb(__('Integrations'), __('Integrations'));
-        $this->_title->add(__('Integrations'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * AJAX integrations grid.
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
     /**
      * Check ACL.
      *
@@ -148,342 +114,6 @@ class Integration extends Action
         return $this->_authorization->isAllowed('Magento_Integration::integrations');
     }
 
-    /**
-     * New integration action.
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Integration::system_integrations');
-        $this->_addBreadcrumb(__('New Integration'), __('New Integration'));
-        $this->_title->add(__('New Integration'));
-        /** Try to recover integration data from session if it was added during previous request which failed. */
-        $restoredIntegration = $this->_getSession()->getIntegrationData();
-        if ($restoredIntegration) {
-            $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $restoredIntegration);
-            $this->_getSession()->setIntegrationData(array());
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Edit integration action.
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        /** Try to recover integration data from session if it was added during previous request which failed. */
-        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-        if ($integrationId) {
-            try {
-                $integrationData = $this->_integrationService->get($integrationId)->getData();
-                $originalName = $this->escaper->escapeHtml($integrationData[Info::DATA_NAME]);
-            } catch (IntegrationException $e) {
-                $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->_logger->logException($e);
-                $this->messageManager->addError(__('Internal error. Check exception log for details.'));
-                $this->_redirect('*/*');
-                return;
-            }
-            $restoredIntegration = $this->_getSession()->getIntegrationData();
-            if (isset($restoredIntegration[Info::DATA_ID]) && $integrationId == $restoredIntegration[Info::DATA_ID]) {
-                $integrationData = array_merge($integrationData, $restoredIntegration);
-            }
-        } else {
-            $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
-            $this->_redirect('*/*/');
-            return;
-        }
-        $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
-        $this->_view->loadLayout();
-        $this->_getSession()->setIntegrationData(array());
-        $this->_setActiveMenu('Magento_Integration::system_integrations');
-
-        if ($this->_integrationData->isConfigType($integrationData)) {
-            $title = __('View "%1" Integration', $originalName);
-        } else {
-            $title = __('Edit "%1" Integration', $originalName);
-        }
-
-        $this->_addBreadcrumb($title, $title);
-        $this->_title->add($title);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save integration action.
-     *
-     * @return void
-     * @todo: Fix cyclomatic complexity.
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function saveAction()
-    {
-        /** @var array $integrationData */
-        $integrationData = array();
-        try {
-            $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-            if ($integrationId) {
-                try {
-                    $integrationData = $this->_integrationService->get($integrationId)->getData();
-                } catch (IntegrationException $e) {
-                    $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-                    $this->_redirect('*/*/');
-                    return;
-                } catch (\Exception $e) {
-                    $this->_logger->logException($e);
-                    $this->messageManager->addError(__('Internal error. Check exception log for details.'));
-                    $this->_redirect('*/*');
-                    return;
-                }
-            }
-            /** @var array $data */
-            $data = $this->getRequest()->getPost();
-            if (!empty($data)) {
-                // TODO: Move out work with API permissions to Web API module
-                if (!isset($data['resource'])) {
-                    $integrationData['resource'] = array();
-                }
-                $integrationData = array_merge($integrationData, $data);
-                if (!isset($integrationData[Info::DATA_ID])) {
-                    $integration = $this->_integrationService->create($integrationData);
-                } else {
-                    $integration = $this->_integrationService->update($integrationData);
-                }
-                if (!$this->getRequest()->isXmlHttpRequest()) {
-                    $this->messageManager->addSuccess(
-                        __(
-                            'The integration \'%1\' has been saved.',
-                            $this->escaper->escapeHtml($integration->getName())
-                        )
-                    );
-                }
-                if ($this->getRequest()->isXmlHttpRequest()) {
-                    $isTokenExchange = $integration->getEndpoint() && $integration->getIdentityLinkUrl() ? '1' : '0';
-                    $this->getResponse()->representJson(
-                        $this->_coreHelper->jsonEncode(
-                            array('integrationId' => $integration->getId(), 'isTokenExchange' => $isTokenExchange)
-                        )
-                    );
-                } else {
-                    $this->_redirect('*/*/');
-                }
-            } else {
-                $this->messageManager->addError(__('The integration was not saved.'));
-            }
-        } catch (IntegrationException $e) {
-            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-            $this->_getSession()->setIntegrationData($integrationData);
-            $this->_redirectOnSaveError();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-            $this->_redirectOnSaveError();
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
-            $this->_redirectOnSaveError();
-        }
-    }
-
-    /**
-     * Show permissions popup.
-     *
-     * @return void
-     */
-    public function permissionsDialogAction()
-    {
-        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-        if ($integrationId) {
-            try {
-                $integrationData = $this->_integrationService->get($integrationId)->getData();
-                $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
-            } catch (IntegrationException $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('*/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->_logger->logException($e);
-                $this->messageManager->addError(__('Internal error. Check exception log for details.'));
-                $this->_redirect('*/*');
-                return;
-            }
-        } else {
-            $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        /** Add handles of the tabs which are defined in other modules */
-        $handleNodes = $this->_view->getLayout()->getUpdate()->getFileLayoutUpdatesXml()->xpath(
-            '//referenceBlock[@name="integration.activate.permissions.tabs"]/../@id'
-        );
-        $handles = array();
-        if (is_array($handleNodes)) {
-            foreach ($handleNodes as $node) {
-                $handles[] = (string)$node;
-            }
-        }
-        $this->_view->loadLayout($handles);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Delete the integration.
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-        try {
-            if ($integrationId) {
-                $integrationData = $this->_integrationService->get($integrationId);
-                if ($this->_integrationData->isConfigType($integrationData)) {
-                    $this->messageManager->addError(
-                        __(
-                            "Uninstall the extension to remove integration '%1'.",
-                            $this->escaper->escapeHtml($integrationData[Info::DATA_NAME])
-                        )
-                    );
-                    $this->_redirect('*/*/');
-                    return;
-                }
-                $integrationData = $this->_integrationService->delete($integrationId);
-                if (!$integrationData[Info::DATA_ID]) {
-                    $this->messageManager->addError(__('This integration no longer exists.'));
-                } else {
-                    //Integration deleted successfully, now safe to delete the associated consumer data
-                    if (isset($integrationData[Info::DATA_CONSUMER_ID])) {
-                        $this->_oauthService->deleteConsumer($integrationData[Info::DATA_CONSUMER_ID]);
-                    }
-                    $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
-                    $this->messageManager->addSuccess(
-                        __(
-                            "The integration '%1' has been deleted.",
-                            $this->escaper->escapeHtml($integrationData[Info::DATA_NAME])
-                        )
-                    );
-                }
-            } else {
-                $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
-            }
-        } catch (\Magento\Integration\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-        }
-        $this->_redirect('*/*/');
-    }
-
-    /**
-     * Show tokens popup for simple tokens
-     *
-     * @return void
-     */
-    public function tokensDialogAction()
-    {
-        try {
-            $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-            $integration = $this->_integrationService->get($integrationId);
-            $clearExistingToken = (int)$this->getRequest()->getParam(self::PARAM_REAUTHORIZE, 0);
-            if ($this->_oauthService->createAccessToken($integration->getConsumerId(), $clearExistingToken)) {
-                $integration->setStatus(IntegrationModel::STATUS_ACTIVE)->save();
-            }
-            // Important to call get() once again - that will pull newly generated token
-            $this->_registry->register(
-                self::REGISTRY_KEY_CURRENT_INTEGRATION,
-                $this->_integrationService->get($integrationId)->getData()
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*');
-            return;
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-            $this->messageManager->addError(__('Internal error. Check exception log for details.'));
-            $this->_redirect('*/*');
-            return;
-        }
-        $this->_view->loadLayout(false);
-        //This cannot precede loadlayout(false) else the messages will be removed
-        $this->_setActivationSuccessMsg($clearExistingToken, $integration->getName());
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Post consumer credentials for Oauth integration.
-     *
-     * @return void
-     */
-    public function tokensExchangeAction()
-    {
-        try {
-            $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-            $isReauthorize = (bool)$this->getRequest()->getParam(self::PARAM_REAUTHORIZE, 0);
-            $integration = $this->_integrationService->get($integrationId);
-            if ($isReauthorize) {
-                /** Remove existing token associated with consumer before issuing a new one. */
-                $this->_oauthService->deleteToken($integration->getConsumerId());
-                $integration->setStatus(IntegrationModel::STATUS_INACTIVE)->save();
-            }
-            //Integration chooses to use Oauth for token exchange
-            $this->_oauthService->postToConsumer($integration->getConsumerId(), $integration->getEndpoint());
-            /** Generate JS popup content */
-            $this->_view->loadLayout(false);
-            // Activation or authorization is done only when the Oauth token exchange completes
-            $this->_setActivationInProcessMsg($isReauthorize, $integration->getName());
-            $this->_view->renderLayout();
-            $popupContent = $this->_response->getBody();
-            /** Initialize response body */
-            $result = array(
-                IntegrationModel::IDENTITY_LINK_URL => $integration->getIdentityLinkUrl(),
-                IntegrationModel::CONSUMER_ID => $integration->getConsumerId(),
-                'popup_content' => $popupContent
-            );
-            $this->getResponse()->representJson($this->_coreHelper->jsonEncode($result));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*');
-            return;
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-            $this->messageManager->addError(__('Internal error. Check exception log for details.'));
-            $this->_redirect('*/*');
-            return;
-        }
-    }
-
-    /**
-     * Close window after callback has succeeded
-     *
-     * @return void
-     */
-    public function loginSuccessCallbackAction()
-    {
-        $this->getResponse()->setBody('<script type="text/javascript">setTimeout("self.close()",1000);</script>');
-    }
-
-    /**
-     * Redirect merchant to 'Edit integration' or 'New integration' if error happened during integration save.
-     *
-     * @return void
-     */
-    protected function _redirectOnSaveError()
-    {
-        $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
-        if ($integrationId) {
-            $this->_redirect('*/*/edit', array('id' => $integrationId));
-        } else {
-            $this->_redirect('*/*/new');
-        }
-    }
-
     /**
      * Don't actually redirect if we've got AJAX request - return redirect URL instead.
      *
@@ -502,62 +132,4 @@ class Integration extends Action
             return parent::_redirect($path, $arguments);
         }
     }
-
-    /**
-     * Set success message based on Integration activation or re-authorization.
-     *
-     * @param boolean $isReauthorize Is a re-authorization flow
-     * @param string $integrationName Integration name
-     * @return void
-     */
-    protected function _setActivationSuccessMsg($isReauthorize, $integrationName)
-    {
-        $integrationName = $this->escaper->escapeHtml($integrationName);
-        $successMsg = $isReauthorize ? __(
-            "The integration '%1' has been re-authorized.",
-            $integrationName
-        ) : __(
-            "The integration '%1' has been activated.",
-            $integrationName
-        );
-        $this->messageManager->addSuccess($successMsg);
-    }
-
-    /**
-     * Let the admin know that activation was failed.
-     *
-     * @param bool   $isReauthorize
-     * @param string $integrationName
-     * @return void
-     */
-    protected function _setActivationFailedMsg($isReauthorize, $integrationName)
-    {
-        $msg = $isReauthorize ? __(
-            "Integration '%1' re-authorization has been failed.",
-            $integrationName
-        ) : __(
-            "Integration '%1' activation has been failed.",
-            $integrationName
-        );
-        $this->messageManager->addError($msg);
-    }
-
-    /**
-     * Let the admin know that integration has been sent for activation and token exchange is in process.
-     *
-     * @param bool   $isReauthorize
-     * @param string $integrationName
-     * @return void
-     */
-    protected function _setActivationInProcessMsg($isReauthorize, $integrationName)
-    {
-        $msg = $isReauthorize ? __(
-            "Integration '%1' has been sent for re-authorization.",
-            $integrationName
-        ) : __(
-            "Integration '%1' has been sent for activation.",
-            $integrationName
-        );
-        $this->messageManager->addNotice($msg);
-    }
 }
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad0aaa408c689fe2c9c2c25faa06cb0b58594833
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Delete.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use \Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+
+class Delete extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Delete the integration.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+        try {
+            if ($integrationId) {
+                $integrationData = $this->_integrationService->get($integrationId);
+                if ($this->_integrationData->isConfigType($integrationData)) {
+                    $this->messageManager->addError(
+                        __(
+                            "Uninstall the extension to remove integration '%1'.",
+                            $this->escaper->escapeHtml($integrationData[Info::DATA_NAME])
+                        )
+                    );
+                    $this->_redirect('*/*/');
+                    return;
+                }
+                $integrationData = $this->_integrationService->delete($integrationId);
+                if (!$integrationData[Info::DATA_ID]) {
+                    $this->messageManager->addError(__('This integration no longer exists.'));
+                } else {
+                    //Integration deleted successfully, now safe to delete the associated consumer data
+                    if (isset($integrationData[Info::DATA_CONSUMER_ID])) {
+                        $this->_oauthService->deleteConsumer($integrationData[Info::DATA_CONSUMER_ID]);
+                    }
+                    $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
+                    $this->messageManager->addSuccess(
+                        __(
+                            "The integration '%1' has been deleted.",
+                            $this->escaper->escapeHtml($integrationData[Info::DATA_NAME])
+                        )
+                    );
+                }
+            } else {
+                $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
+            }
+        } catch (\Magento\Integration\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+        }
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..bf4b017a34a8d62716e679a69b952d9e5b28d074
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Edit.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use \Magento\Backend\App\Action;
+use \Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+use \Magento\Integration\Exception as IntegrationException;
+
+class Edit extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Edit integration action.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** Try to recover integration data from session if it was added during previous request which failed. */
+        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+        if ($integrationId) {
+            try {
+                $integrationData = $this->_integrationService->get($integrationId)->getData();
+                $originalName = $this->escaper->escapeHtml($integrationData[Info::DATA_NAME]);
+            } catch (IntegrationException $e) {
+                $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->_logger->logException($e);
+                $this->messageManager->addError(__('Internal error. Check exception log for details.'));
+                $this->_redirect('*/*');
+                return;
+            }
+            $restoredIntegration = $this->_getSession()->getIntegrationData();
+            if (isset($restoredIntegration[Info::DATA_ID]) && $integrationId == $restoredIntegration[Info::DATA_ID]) {
+                $integrationData = array_merge($integrationData, $restoredIntegration);
+            }
+        } else {
+            $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
+            $this->_redirect('*/*/');
+            return;
+        }
+        $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
+        $this->_view->loadLayout();
+        $this->_getSession()->setIntegrationData(array());
+        $this->_setActiveMenu('Magento_Integration::system_integrations');
+
+        if ($this->_integrationData->isConfigType($integrationData)) {
+            $title = __('View "%1" Integration', $originalName);
+        } else {
+            $title = __('Edit "%1" Integration', $originalName);
+        }
+
+        $this->_addBreadcrumb($title, $title);
+        $this->_title->add($title);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Grid.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..25588fc738d2336324a46c30ca0c76832618e281
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+class Grid extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * AJAX integrations grid.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Index.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..031bd0bd52b2f9e2b17c90ae2ceffcac703c60b8
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Index.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+class Index extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Integrations grid.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $unsecureIntegrationsCount = $this->_integrationCollection->addUnsecureUrlsFilter()->getSize();
+        if ($unsecureIntegrationsCount > 0) {
+            // @codingStandardsIgnoreStart
+            $this->messageManager->addNotice(__('Warning! Integrations not using HTTPS are insecure and potentially expose private or personally identifiable information')
+            // @codingStandardsIgnoreEnd
+            );
+        }
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Integration::system_integrations');
+        $this->_addBreadcrumb(__('Integrations'), __('Integrations'));
+        $this->_title->add(__('Integrations'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/LoginSuccessCallback.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/LoginSuccessCallback.php
new file mode 100644
index 0000000000000000000000000000000000000000..cfcc0662d7341590a2bf0e308eb523081b724ed6
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/LoginSuccessCallback.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+class LoginSuccessCallback extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Close window after callback has succeeded
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody('<script type="text/javascript">setTimeout("self.close()",1000);</script>');
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/NewAction.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a3abc24e6e8f9624b3e60d0897263f038a9687a
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/NewAction.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+class NewAction extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * New integration action.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Integration::system_integrations');
+        $this->_addBreadcrumb(__('New Integration'), __('New Integration'));
+        $this->_title->add(__('New Integration'));
+        /** Try to recover integration data from session if it was added during previous request which failed. */
+        $restoredIntegration = $this->_getSession()->getIntegrationData();
+        if ($restoredIntegration) {
+            $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $restoredIntegration);
+            $this->_getSession()->setIntegrationData(array());
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php
new file mode 100644
index 0000000000000000000000000000000000000000..9c495d0288a9a0fb5db408a5261c870d6b687860
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialog.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Integration\Exception as IntegrationException;
+
+class PermissionsDialog extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Show permissions popup.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+        if ($integrationId) {
+            try {
+                $integrationData = $this->_integrationService->get($integrationId)->getData();
+                $this->_registry->register(self::REGISTRY_KEY_CURRENT_INTEGRATION, $integrationData);
+            } catch (IntegrationException $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('*/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->_logger->logException($e);
+                $this->messageManager->addError(__('Internal error. Check exception log for details.'));
+                $this->_redirect('*/*');
+                return;
+            }
+        } else {
+            $this->messageManager->addError(__('Integration ID is not specified or is invalid.'));
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        /** Add handles of the tabs which are defined in other modules */
+        $handleNodes = $this->_view->getLayout()->getUpdate()->getFileLayoutUpdatesXml()->xpath(
+            '//referenceBlock[@name="integration.activate.permissions.tabs"]/../@id'
+        );
+        $handles = array();
+        if (is_array($handleNodes)) {
+            foreach ($handleNodes as $node) {
+                $handles[] = (string)$node;
+            }
+        }
+        $this->_view->loadLayout($handles);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..726e6ea4bd42696c7b3fa3110e2788ba8dad67b3
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/Save.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use \Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+use Magento\Integration\Exception as IntegrationException;
+
+class Save extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Redirect merchant to 'Edit integration' or 'New integration' if error happened during integration save.
+     *
+     * @return void
+     */
+    protected function _redirectOnSaveError()
+    {
+        $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+        if ($integrationId) {
+            $this->_redirect('*/*/edit', array('id' => $integrationId));
+        } else {
+            $this->_redirect('*/*/new');
+        }
+    }
+
+    /**
+     * Save integration action.
+     *
+     * @return void
+     * @todo: Fix cyclomatic complexity.
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        /** @var array $integrationData */
+        $integrationData = array();
+        try {
+            $integrationId = (int)$this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+            if ($integrationId) {
+                try {
+                    $integrationData = $this->_integrationService->get($integrationId)->getData();
+                } catch (IntegrationException $e) {
+                    $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+                    $this->_redirect('*/*/');
+                    return;
+                } catch (\Exception $e) {
+                    $this->_logger->logException($e);
+                    $this->messageManager->addError(__('Internal error. Check exception log for details.'));
+                    $this->_redirect('*/*');
+                    return;
+                }
+            }
+            /** @var array $data */
+            $data = $this->getRequest()->getPost();
+            if (!empty($data)) {
+                // TODO: Move out work with API permissions to Web API module
+                if (!isset($data['resource'])) {
+                    $integrationData['resource'] = array();
+                }
+                $integrationData = array_merge($integrationData, $data);
+                if (!isset($integrationData[Info::DATA_ID])) {
+                    $integration = $this->_integrationService->create($integrationData);
+                } else {
+                    $integration = $this->_integrationService->update($integrationData);
+                }
+                if (!$this->getRequest()->isXmlHttpRequest()) {
+                    $this->messageManager->addSuccess(
+                        __(
+                            'The integration \'%1\' has been saved.',
+                            $this->escaper->escapeHtml($integration->getName())
+                        )
+                    );
+                }
+                if ($this->getRequest()->isXmlHttpRequest()) {
+                    $isTokenExchange = $integration->getEndpoint() && $integration->getIdentityLinkUrl() ? '1' : '0';
+                    $this->getResponse()->representJson(
+                        $this->_coreHelper->jsonEncode(
+                            array('integrationId' => $integration->getId(), 'isTokenExchange' => $isTokenExchange)
+                        )
+                    );
+                } else {
+                    $this->_redirect('*/*/');
+                }
+            } else {
+                $this->messageManager->addError(__('The integration was not saved.'));
+            }
+        } catch (IntegrationException $e) {
+            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+            $this->_getSession()->setIntegrationData($integrationData);
+            $this->_redirectOnSaveError();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+            $this->_redirectOnSaveError();
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+            $this->messageManager->addError($this->escaper->escapeHtml($e->getMessage()));
+            $this->_redirectOnSaveError();
+        }
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php
new file mode 100644
index 0000000000000000000000000000000000000000..4f94ab274405088d64c86337d917c61c62e575de
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensDialog.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use \Magento\Integration\Model\Integration as IntegrationModel;
+
+class TokensDialog extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Set success message based on Integration activation or re-authorization.
+     *
+     * @param boolean $isReauthorize Is a re-authorization flow
+     * @param string $integrationName Integration name
+     * @return void
+     */
+    protected function _setActivationSuccessMsg($isReauthorize, $integrationName)
+    {
+        $integrationName = $this->escaper->escapeHtml($integrationName);
+        $successMsg = $isReauthorize ? __(
+            "The integration '%1' has been re-authorized.",
+            $integrationName
+        ) : __(
+            "The integration '%1' has been activated.",
+            $integrationName
+        );
+        $this->messageManager->addSuccess($successMsg);
+    }
+
+    /**
+     * Show tokens popup for simple tokens
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+            $integration = $this->_integrationService->get($integrationId);
+            $clearExistingToken = (int)$this->getRequest()->getParam(self::PARAM_REAUTHORIZE, 0);
+            if ($this->_oauthService->createAccessToken($integration->getConsumerId(), $clearExistingToken)) {
+                $integration->setStatus(IntegrationModel::STATUS_ACTIVE)->save();
+            }
+            // Important to call get() once again - that will pull newly generated token
+            $this->_registry->register(
+                self::REGISTRY_KEY_CURRENT_INTEGRATION,
+                $this->_integrationService->get($integrationId)->getData()
+            );
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*');
+            return;
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+            $this->messageManager->addError(__('Internal error. Check exception log for details.'));
+            $this->_redirect('*/*');
+            return;
+        }
+        $this->_view->loadLayout(false);
+        //This cannot precede loadlayout(false) else the messages will be removed
+        $this->_setActivationSuccessMsg($clearExistingToken, $integration->getName());
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c68fd46dfd4afc244560c62497ef220b37da9ee
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Adminhtml/Integration/TokensExchange.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use \Magento\Integration\Model\Integration as IntegrationModel;
+
+class TokensExchange extends \Magento\Integration\Controller\Adminhtml\Integration
+{
+    /**
+     * Let the admin know that integration has been sent for activation and token exchange is in process.
+     *
+     * @param bool   $isReauthorize
+     * @param string $integrationName
+     * @return void
+     */
+    protected function _setActivationInProcessMsg($isReauthorize, $integrationName)
+    {
+        $msg = $isReauthorize ? __(
+            "Integration '%1' has been sent for re-authorization.",
+            $integrationName
+        ) : __(
+            "Integration '%1' has been sent for activation.",
+            $integrationName
+        );
+        $this->messageManager->addNotice($msg);
+    }
+
+    /**
+     * Post consumer credentials for Oauth integration.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $integrationId = $this->getRequest()->getParam(self::PARAM_INTEGRATION_ID);
+            $isReauthorize = (bool)$this->getRequest()->getParam(self::PARAM_REAUTHORIZE, 0);
+            $integration = $this->_integrationService->get($integrationId);
+            if ($isReauthorize) {
+                /** Remove existing token associated with consumer before issuing a new one. */
+                $this->_oauthService->deleteToken($integration->getConsumerId());
+                $integration->setStatus(IntegrationModel::STATUS_INACTIVE)->save();
+            }
+            //Integration chooses to use Oauth for token exchange
+            $this->_oauthService->postToConsumer($integration->getConsumerId(), $integration->getEndpoint());
+            /** Generate JS popup content */
+            $this->_view->loadLayout(false);
+            // Activation or authorization is done only when the Oauth token exchange completes
+            $this->_setActivationInProcessMsg($isReauthorize, $integration->getName());
+            $this->_view->renderLayout();
+            $popupContent = $this->_response->getBody();
+            /** Initialize response body */
+            $result = array(
+                IntegrationModel::IDENTITY_LINK_URL => $integration->getIdentityLinkUrl(),
+                IntegrationModel::CONSUMER_ID => $integration->getConsumerId(),
+                'popup_content' => $popupContent
+            );
+            $this->getResponse()->representJson($this->_coreHelper->jsonEncode($result));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*');
+            return;
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+            $this->messageManager->addError(__('Internal error. Check exception log for details.'));
+            $this->_redirect('*/*');
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Integration/Controller/Token.php b/app/code/Magento/Integration/Controller/Token/Access.php
similarity index 71%
rename from app/code/Magento/Integration/Controller/Token.php
rename to app/code/Magento/Integration/Controller/Token/Access.php
index e3d368fe196948b968a13a111cac5ccc2851d343..2d1dea463ddf9d18f3a38296ea31725fcb5e1d74 100644
--- a/app/code/Magento/Integration/Controller/Token.php
+++ b/app/code/Magento/Integration/Controller/Token/Access.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -18,30 +19,35 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
- * @copyright  Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license    http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Integration\Controller;
+namespace Magento\Integration\Controller\Token;
 
 use Magento\Integration\Service\V1\OauthInterface as IntegrationOauthService;
 use Magento\Integration\Service\V1\IntegrationInterface as IntegrationService;
 use Magento\Integration\Model\Integration as IntegrationModel;
 
-/**
- * oAuth token controller
- */
-class Token extends \Magento\Framework\App\Action\Action
+class Access extends \Magento\Framework\App\Action\Action
 {
-    /** @var  \Magento\Framework\Oauth\OauthInterface */
+    /**
+     * @var  \Magento\Framework\Oauth\OauthInterface
+     */
     protected $_oauthService;
 
-    /** @var  IntegrationOauthService */
+    /**
+     * @var  IntegrationOauthService
+     */
     protected $_intOauthService;
 
-    /** @var  IntegrationService */
+    /**
+     * @var  IntegrationService
+     */
     protected $_integrationService;
 
-    /** @var  \Magento\Framework\Oauth\Helper\Request */
+    /**
+     * @var  \Magento\Framework\Oauth\Helper\Request
+     */
     protected $_helper;
 
     /**
@@ -65,31 +71,12 @@ class Token extends \Magento\Framework\App\Action\Action
         $this->_helper = $helper;
     }
 
-    /**
-     *  Initiate RequestToken request operation
-     *
-     * @return void
-     */
-    public function requestAction()
-    {
-        try {
-            $requestUrl = $this->_helper->getRequestUrl($this->getRequest());
-            $request = $this->_helper->prepareRequest($this->getRequest(), $requestUrl);
-
-            // Request request token
-            $response = $this->_oauthService->getRequestToken($request, $requestUrl, $this->getRequest()->getMethod());
-        } catch (\Exception $exception) {
-            $response = $this->_helper->prepareErrorResponse($exception, $this->getResponse());
-        }
-        $this->getResponse()->setBody(http_build_query($response));
-    }
-
     /**
      * Initiate AccessToken request operation
      *
      * @return void
      */
-    public function accessAction()
+    public function execute()
     {
         try {
             $requestUrl = $this->_helper->getRequestUrl($this->getRequest());
diff --git a/app/code/Magento/Integration/Controller/Token/Request.php b/app/code/Magento/Integration/Controller/Token/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..b39bf1289cd26e2f2ee89eeaeb115d88ff5211d2
--- /dev/null
+++ b/app/code/Magento/Integration/Controller/Token/Request.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Token;
+
+class Request extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var  \Magento\Framework\Oauth\OauthInterface
+     */
+    protected $_oauthService;
+
+    /**
+     * @var  \Magento\Framework\Oauth\Helper\Request
+     */
+    protected $_helper;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Framework\Oauth\OauthInterface $oauthService
+     * @param \Magento\Framework\Oauth\Helper\Request $helper
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Oauth\OauthInterface $oauthService,
+        \Magento\Framework\Oauth\Helper\Request $helper
+    ) {
+        parent::__construct($context);
+        $this->_oauthService = $oauthService;
+        $this->_helper = $helper;
+    }
+
+    /**
+     *  Initiate RequestToken request operation
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $requestUrl = $this->_helper->getRequestUrl($this->getRequest());
+            $request = $this->_helper->prepareRequest($this->getRequest(), $requestUrl);
+
+            // Request request token
+            $response = $this->_oauthService->getRequestToken($request, $requestUrl, $this->getRequest()->getMethod());
+        } catch (\Exception $exception) {
+            $response = $this->_helper->prepareErrorResponse($exception, $this->getResponse());
+        }
+        $this->getResponse()->setBody(http_build_query($response));
+    }
+}
diff --git a/app/code/Magento/Integration/i18n/de_DE.csv b/app/code/Magento/Integration/i18n/de_DE.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/de_DE.csv
+++ b/app/code/Magento/Integration/i18n/de_DE.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/en_US.csv b/app/code/Magento/Integration/i18n/en_US.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/en_US.csv
+++ b/app/code/Magento/Integration/i18n/en_US.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/es_ES.csv b/app/code/Magento/Integration/i18n/es_ES.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/es_ES.csv
+++ b/app/code/Magento/Integration/i18n/es_ES.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/fr_FR.csv b/app/code/Magento/Integration/i18n/fr_FR.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/fr_FR.csv
+++ b/app/code/Magento/Integration/i18n/fr_FR.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/nl_NL.csv b/app/code/Magento/Integration/i18n/nl_NL.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/nl_NL.csv
+++ b/app/code/Magento/Integration/i18n/nl_NL.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/pt_BR.csv b/app/code/Magento/Integration/i18n/pt_BR.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/pt_BR.csv
+++ b/app/code/Magento/Integration/i18n/pt_BR.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Integration/i18n/zh_CN.csv b/app/code/Magento/Integration/i18n/zh_CN.csv
index 97f437e86737345a18f515a62bdebbb515fb408c..285c9c3aa115fb17d870a32ee1d7418c8aaeb7a9 100644
--- a/app/code/Magento/Integration/i18n/zh_CN.csv
+++ b/app/code/Magento/Integration/i18n/zh_CN.csv
@@ -42,8 +42,6 @@ Reauthorize,Reauthorize
 "The integration '%1' has been deleted.","The integration '%1' has been deleted."
 "The integration '%1' has been re-authorized.","The integration '%1' has been re-authorized."
 "The integration '%1' has been activated.","The integration '%1' has been activated."
-"Integration '%1' re-authorization has been failed.","Integration '%1' re-authorization has been failed."
-"Integration '%1' activation has been failed.","Integration '%1' activation has been failed."
 "Integration '%1' has been sent for re-authorization.","Integration '%1' has been sent for re-authorization."
 "Integration '%1' has been sent for activation.","Integration '%1' has been sent for activation."
 "Invalid Callback URL","Invalid Callback URL"
diff --git a/app/code/Magento/Multishipping/Controller/Checkout.php b/app/code/Magento/Multishipping/Controller/Checkout.php
index 391cd0e907f5f64f7e0de514667802224b0c95aa..57fce47e3492297b3213edad20e658c41923e532 100755
--- a/app/code/Magento/Multishipping/Controller/Checkout.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout.php
@@ -24,7 +24,6 @@
 namespace Magento\Multishipping\Controller;
 
 use Magento\Framework\App\RequestInterface;
-use Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface as CustomerAccountService;
 use Magento\Customer\Service\V1\CustomerMetadataServiceInterface as CustomerMetadataService;
 
@@ -165,156 +164,6 @@ class Checkout extends \Magento\Checkout\Controller\Action implements
         return parent::dispatch($request);
     }
 
-    /**
-     * Index action of Multishipping checkout
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_getCheckoutSession()->setCartWasUpdated(false);
-        $this->_redirect('*/*/addresses');
-    }
-
-    /**
-     * Multishipping checkout login page
-     *
-     * @return void
-     */
-    public function loginAction()
-    {
-        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-            $this->_redirect('*/*/');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        // set account create url
-        $loginForm = $this->_view->getLayout()->getBlock('customer.new');
-        if ($loginForm) {
-            $loginForm->setCreateAccountUrl($this->_getHelper()->getMSRegisterUrl());
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Multishipping checkout login page
-     *
-     * @return void
-     */
-    public function registerAction()
-    {
-        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-            $this->getResponse()->setRedirect($this->_getHelper()->getMSCheckoutUrl());
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $registerForm = $this->_view->getLayout()->getBlock('customer_form_register');
-        if ($registerForm) {
-            $registerForm->setShowAddressFields(
-                true
-            )->setBackUrl(
-                $this->_getHelper()->getMSLoginUrl()
-            )->setSuccessUrl(
-                $this->_getHelper()->getMSShippingAddressSavedUrl()
-            )->setErrorUrl(
-                $this->_url->getCurrentUrl()
-            );
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Multishipping checkout select address page
-     *
-     * @return void
-     */
-    public function addressesAction()
-    {
-        // If customer do not have addresses
-        if (!$this->_getCheckout()->getCustomerDefaultShippingAddress()) {
-            $this->_redirect('*/checkout_address/newShipping');
-            return;
-        }
-
-        $this->_getState()->unsCompleteStep(State::STEP_SHIPPING);
-
-        $this->_getState()->setActiveStep(State::STEP_SELECT_ADDRESSES);
-        if (!$this->_getCheckout()->validateMinimumAmount()) {
-            $message = $this->_getCheckout()->getMinimumAmountDescription();
-            $this->messageManager->addNotice($message);
-        }
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Multishipping checkout process posted addresses
-     *
-     * @return void
-     */
-    public function addressesPostAction()
-    {
-        if (!$this->_getCheckout()->getCustomerDefaultShippingAddress()) {
-            $this->_redirect('*/checkout_address/newShipping');
-            return;
-        }
-        try {
-            if ($this->getRequest()->getParam('continue', false)) {
-                $this->_getCheckout()->setCollectRatesFlag(true);
-                $this->_getState()->setActiveStep(State::STEP_SHIPPING);
-                $this->_getState()->setCompleteStep(State::STEP_SELECT_ADDRESSES);
-                $this->_redirect('*/*/shipping');
-            } elseif ($this->getRequest()->getParam('new_address')) {
-                $this->_redirect('*/checkout_address/newShipping');
-            } else {
-                $this->_redirect('*/*/addresses');
-            }
-            if ($shipToInfo = $this->getRequest()->getPost('ship')) {
-                $this->_getCheckout()->setShippingItemsInformation($shipToInfo);
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/addresses');
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Data saving problem'));
-            $this->_redirect('*/*/addresses');
-        }
-    }
-
-    /**
-     * @return void
-     */
-    public function backToAddressesAction()
-    {
-        $this->_getState()->setActiveStep(State::STEP_SELECT_ADDRESSES);
-        $this->_getState()->unsCompleteStep(State::STEP_SHIPPING);
-        $this->_redirect('*/*/addresses');
-    }
-
-    /**
-     * Multishipping checkout remove item action
-     *
-     * @return void
-     */
-    public function removeItemAction()
-    {
-        $itemId = $this->getRequest()->getParam('id');
-        $addressId = $this->getRequest()->getParam('address');
-        if ($addressId && $itemId) {
-            $this->_getCheckout()->setCollectRatesFlag(true);
-            $this->_getCheckout()->removeAddressItem($addressId, $itemId);
-        }
-        $this->_redirect('*/*/addresses');
-    }
-
     /**
      * Validate minimum amount
      *
@@ -331,242 +180,6 @@ class Checkout extends \Magento\Checkout\Controller\Action implements
         return true;
     }
 
-    /**
-     * Multishipping checkout shipping information page
-     *
-     * @return  ResponseInterface|void
-     */
-    public function shippingAction()
-    {
-        if (!$this->_validateMinimumAmount()) {
-            return;
-        }
-
-        if (!$this->_getState()->getCompleteStep(State::STEP_SELECT_ADDRESSES)) {
-            return $this->_redirect('*/*/addresses');
-        }
-
-        $this->_getState()->setActiveStep(State::STEP_SHIPPING);
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function backToShippingAction()
-    {
-        $this->_getState()->setActiveStep(State::STEP_SHIPPING);
-        $this->_getState()->unsCompleteStep(State::STEP_BILLING);
-        $this->_redirect('*/*/shipping');
-    }
-
-    /**
-     * @return void
-     */
-    public function shippingPostAction()
-    {
-        $shippingMethods = $this->getRequest()->getPost('shipping_method');
-        try {
-            $this->_eventManager->dispatch(
-                'checkout_controller_multishipping_shipping_post',
-                array('request' => $this->getRequest(), 'quote' => $this->_getCheckout()->getQuote())
-            );
-            $this->_getCheckout()->setShippingMethods($shippingMethods);
-            $this->_getState()->setActiveStep(State::STEP_BILLING);
-            $this->_getState()->setCompleteStep(State::STEP_SHIPPING);
-            $this->_redirect('*/*/billing');
-        } catch (\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/shipping');
-        }
-    }
-
-    /**
-     * Multishipping checkout billing information page
-     *
-     * @return void|ResponseInterface
-     */
-    public function billingAction()
-    {
-        if (!$this->_validateBilling()) {
-            return;
-        }
-
-        if (!$this->_validateMinimumAmount()) {
-            return;
-        }
-
-        if (!$this->_getState()->getCompleteStep(State::STEP_SHIPPING)) {
-            return $this->_redirect('*/*/shipping');
-        }
-
-        $this->_getState()->setActiveStep(State::STEP_BILLING);
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Validation of selecting of billing address
-     *
-     * @return boolean
-     */
-    protected function _validateBilling()
-    {
-        if (!$this->_getCheckout()->getQuote()->getBillingAddress()->getFirstname()) {
-            $this->_redirect('*/checkout_address/selectBilling');
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Back to billing action
-     *
-     * @return void
-     */
-    public function backToBillingAction()
-    {
-        $this->_getState()->setActiveStep(State::STEP_BILLING);
-        $this->_getState()->unsCompleteStep(State::STEP_OVERVIEW);
-        $this->_redirect('*/*/billing');
-    }
-
-    /**
-     * Multishipping checkout place order page
-     *
-     * @return void
-     */
-    public function overviewAction()
-    {
-        if (!$this->_validateMinimumAmount()) {
-            return;
-        }
-
-        $this->_getState()->setActiveStep(State::STEP_OVERVIEW);
-
-        try {
-            $payment = $this->getRequest()->getPost('payment', array());
-            $payment['checks'] = array(
-                \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
-                \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
-                \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
-                \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
-            );
-            $this->_getCheckout()->setPaymentMethod($payment);
-
-            $this->_getState()->setCompleteStep(State::STEP_BILLING);
-
-            $this->_view->loadLayout();
-            $this->_view->getLayout()->initMessages();
-            $this->_view->renderLayout();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/billing');
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addException($e, __('We cannot open the overview page.'));
-            $this->_redirect('*/*/billing');
-        }
-    }
-
-    /**
-     * Overview action
-     *
-     * @return void
-     */
-    public function overviewPostAction()
-    {
-        if (!$this->_validateMinimumAmount()) {
-            return;
-        }
-
-        try {
-            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
-            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', array())))) {
-                $this->messageManager->addError(
-                    __('Please agree to all Terms and Conditions before placing the order.')
-                );
-                $this->_redirect('*/*/billing');
-                return;
-            }
-
-            $payment = $this->getRequest()->getPost('payment');
-            $paymentInstance = $this->_getCheckout()->getQuote()->getPayment();
-            if (isset($payment['cc_number'])) {
-                $paymentInstance->setCcNumber($payment['cc_number']);
-            }
-            if (isset($payment['cc_cid'])) {
-                $paymentInstance->setCcCid($payment['cc_cid']);
-            }
-            $this->_getCheckout()->createOrders();
-            $this->_getState()->setActiveStep(State::STEP_SUCCESS);
-            $this->_getState()->setCompleteStep(State::STEP_OVERVIEW);
-            $this->_getCheckout()->getCheckoutSession()->clearQuote();
-            $this->_getCheckout()->getCheckoutSession()->setDisplaySuccess(true);
-            $this->_redirect('*/*/success');
-        } catch (\Magento\Payment\Model\Info\Exception $e) {
-            $message = $e->getMessage();
-            if (!empty($message)) {
-                $this->messageManager->addError($message);
-            }
-            $this->_redirect('*/*/billing');
-        } catch (\Magento\Checkout\Exception $e) {
-            $this->_objectManager->get(
-                'Magento\Checkout\Helper\Data'
-            )->sendPaymentFailedEmail(
-                $this->_getCheckout()->getQuote(),
-                $e->getMessage(),
-                'multi-shipping'
-            );
-            $this->_getCheckout()->getCheckoutSession()->clearQuote();
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/cart');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_objectManager->get(
-                'Magento\Checkout\Helper\Data'
-            )->sendPaymentFailedEmail(
-                $this->_getCheckout()->getQuote(),
-                $e->getMessage(),
-                'multi-shipping'
-            );
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/billing');
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_objectManager->get(
-                'Magento\Checkout\Helper\Data'
-            )->sendPaymentFailedEmail(
-                $this->_getCheckout()->getQuote(),
-                $e->getMessage(),
-                'multi-shipping'
-            );
-            $this->messageManager->addError(__('Order place error'));
-            $this->_redirect('*/*/billing');
-        }
-    }
-
-    /**
-     * Multishipping checkout success page
-     *
-     * @return void
-     */
-    public function successAction()
-    {
-        if (!$this->_getState()->getCompleteStep(State::STEP_OVERVIEW)) {
-            $this->_redirect('*/*/addresses');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $ids = $this->_getCheckout()->getOrderIds();
-        $this->_eventManager->dispatch('multishipping_checkout_controller_success_action', array('order_ids' => $ids));
-        $this->_view->renderLayout();
-    }
-
     /**
      * Returns before_auth_url redirect parameter for customer session
      *
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address.php b/app/code/Magento/Multishipping/Controller/Checkout/Address.php
index f6ef6f2b51310c2f6ca18475eb5b71b73a63974f..27729eb2ab34664034e1b8fc5e6eee0ff42e0850 100644
--- a/app/code/Magento/Multishipping/Controller/Checkout/Address.php
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address.php
@@ -23,31 +23,11 @@
  */
 namespace Magento\Multishipping\Controller\Checkout;
 
-use Magento\Framework\App\Action\Context;
-use Magento\Customer\Service\V1\CustomerAddressServiceInterface;
-
 /**
  * Multishipping checkout address manipulation controller
  */
 class Address extends \Magento\Framework\App\Action\Action
 {
-    /** @var CustomerAddressServiceInterface */
-    protected $_customerAddressService;
-
-    /**
-     * Initialize dependencies.
-     *
-     * @param Context $context
-     * @param CustomerAddressServiceInterface $customerAddressService
-     */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        CustomerAddressServiceInterface $customerAddressService
-    ) {
-        $this->_customerAddressService = $customerAddressService;
-        parent::__construct($context);
-    }
-
     /**
      * Retrieve multishipping checkout model
      *
@@ -67,218 +47,4 @@ class Address extends \Magento\Framework\App\Action\Action
     {
         return $this->_objectManager->get('Magento\Multishipping\Model\Checkout\Type\Multishipping\State');
     }
-
-    /**
-     * Create New Shipping address Form
-     *
-     * @return void
-     */
-    public function newShippingAction()
-    {
-        $this->_getState()->setActiveStep(
-            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_SELECT_ADDRESSES
-        );
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
-            $addressForm->setTitle(
-                __('Create Shipping Address')
-            )->setSuccessUrl(
-                $this->_url->getUrl('*/*/shippingSaved')
-            )->setErrorUrl(
-                $this->_url->getUrl('*/*/*')
-            );
-
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
-
-            if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
-                $addressForm->setBackUrl($this->_url->getUrl('*/checkout/addresses'));
-            } else {
-                $addressForm->setBackUrl($this->_url->getUrl('*/cart/'));
-            }
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function shippingSavedAction()
-    {
-        /**
-         * if we create first address we need reset emd init checkout
-         */
-        $customerId = $this->_getCheckout()->getCustomer()->getId();
-        if (count($this->_customerAddressService->getAddresses($customerId)) == 1) {
-            $this->_getCheckout()->reset();
-        }
-        $this->_redirect('*/checkout/addresses');
-    }
-
-    /**
-     * @return void
-     */
-    public function editShippingAction()
-    {
-        $this->_getState()->setActiveStep(
-            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_SHIPPING
-        );
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
-            $addressForm->setTitle(
-                __('Edit Shipping Address')
-            )->setSuccessUrl(
-                $this->_url->getUrl('*/*/editShippingPost', array('id' => $this->getRequest()->getParam('id')))
-            )->setErrorUrl(
-                $this->_url->getUrl('*/*/*')
-            );
-
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
-
-            if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
-                $addressForm->setBackUrl($this->_url->getUrl('*/checkout/shipping'));
-            }
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editShippingPostAction()
-    {
-        if ($addressId = $this->getRequest()->getParam('id')) {
-            $this->_objectManager->create(
-                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
-            )->updateQuoteCustomerShippingAddress(
-                $addressId
-            );
-        }
-        $this->_redirect('*/checkout/shipping');
-    }
-
-    /**
-     * @return void
-     */
-    public function selectBillingAction()
-    {
-        $this->_getState()->setActiveStep(
-            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_BILLING
-        );
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newBillingAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
-            $addressForm->setTitle(
-                __('Create Billing Address')
-            )->setSuccessUrl(
-                $this->_url->getUrl('*/*/selectBilling')
-            )->setErrorUrl(
-                $this->_url->getUrl('*/*/*')
-            )->setBackUrl(
-                $this->_url->getUrl('*/*/selectBilling')
-            );
-
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editAddressAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
-            $addressForm->setTitle(
-                __('Edit Address')
-            )->setSuccessUrl(
-                $this->_url->getUrl('*/*/selectBilling')
-            )->setErrorUrl(
-                $this->_url->getUrl('*/*/*', array('id' => $this->getRequest()->getParam('id')))
-            )->setBackUrl(
-                $this->_url->getUrl('*/*/selectBilling')
-            );
-
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editBillingAction()
-    {
-        $this->_getState()->setActiveStep(
-            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_BILLING
-        );
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
-            $addressForm->setTitle(
-                __('Edit Billing Address')
-            )->setSuccessUrl(
-                $this->_url->getUrl('*/*/saveBilling', array('id' => $this->getRequest()->getParam('id')))
-            )->setErrorUrl(
-                $this->_url->getUrl('*/*/*', array('id' => $this->getRequest()->getParam('id')))
-            )->setBackUrl(
-                $this->_url->getUrl('*/checkout/overview')
-            );
-            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
-                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
-            }
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function setBillingAction()
-    {
-        if ($addressId = $this->getRequest()->getParam('id')) {
-            $this->_objectManager->create(
-                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
-            )->setQuoteCustomerBillingAddress(
-                $addressId
-            );
-        }
-        $this->_redirect('*/checkout/billing');
-    }
-
-    /**
-     * @return void
-     */
-    public function saveBillingAction()
-    {
-        if ($addressId = $this->getRequest()->getParam('id')) {
-            $this->_objectManager->create(
-                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
-            )->setQuoteCustomerBillingAddress(
-                $addressId
-            );
-        }
-        $this->_redirect('*/checkout/overview');
-    }
 }
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc038bcbe187c8c07c80e06b25b4bfeb32bd4375
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditAddress.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class EditAddress extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
+            $addressForm->setTitle(
+                __('Edit Address')
+            )->setSuccessUrl(
+                $this->_url->getUrl('*/*/selectBilling')
+            )->setErrorUrl(
+                $this->_url->getUrl('*/*/*', array('id' => $this->getRequest()->getParam('id')))
+            )->setBackUrl(
+                $this->_url->getUrl('*/*/selectBilling')
+            );
+
+            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
+                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
+            }
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..9123868193fa0b11d0e49f61fda6d1565e392be4
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditBilling.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class EditBilling extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(
+            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_BILLING
+        );
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
+            $addressForm->setTitle(
+                __('Edit Billing Address')
+            )->setSuccessUrl(
+                $this->_url->getUrl('*/*/saveBilling', array('id' => $this->getRequest()->getParam('id')))
+            )->setErrorUrl(
+                $this->_url->getUrl('*/*/*', array('id' => $this->getRequest()->getParam('id')))
+            )->setBackUrl(
+                $this->_url->getUrl('*/checkout/overview')
+            );
+            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
+                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
+            }
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a68b1c7f43a303d00440524024051556ed45fef
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShipping.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class EditShipping extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(
+            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_SHIPPING
+        );
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
+            $addressForm->setTitle(
+                __('Edit Shipping Address')
+            )->setSuccessUrl(
+                $this->_url->getUrl('*/*/editShippingPost', array('id' => $this->getRequest()->getParam('id')))
+            )->setErrorUrl(
+                $this->_url->getUrl('*/*/*')
+            );
+
+            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
+                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
+            }
+
+            if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
+                $addressForm->setBackUrl($this->_url->getUrl('*/checkout/shipping'));
+            }
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShippingPost.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShippingPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3473e2da3cdc9499253d83df3087b1047047409
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/EditShippingPost.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class EditShippingPost extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($addressId = $this->getRequest()->getParam('id')) {
+            $this->_objectManager->create(
+                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
+            )->updateQuoteCustomerShippingAddress(
+                $addressId
+            );
+        }
+        $this->_redirect('*/checkout/shipping');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..c18e5636670ef83098bce743456ac1ef22a8f28f
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewBilling.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class NewBilling extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
+            $addressForm->setTitle(
+                __('Create Billing Address')
+            )->setSuccessUrl(
+                $this->_url->getUrl('*/*/selectBilling')
+            )->setErrorUrl(
+                $this->_url->getUrl('*/*/*')
+            )->setBackUrl(
+                $this->_url->getUrl('*/*/selectBilling')
+            );
+
+            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
+                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
+            }
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..24675a291c57a1aa60edd6b135bbbad292a1e129
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/NewShipping.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class NewShipping extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * Create New Shipping address Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(
+            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_SELECT_ADDRESSES
+        );
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        if ($addressForm = $this->_view->getLayout()->getBlock('customer_address_edit')) {
+            $addressForm->setTitle(
+                __('Create Shipping Address')
+            )->setSuccessUrl(
+                $this->_url->getUrl('*/*/shippingSaved')
+            )->setErrorUrl(
+                $this->_url->getUrl('*/*/*')
+            );
+
+            if ($headBlock = $this->_view->getLayout()->getBlock('head')) {
+                $headBlock->setTitle($addressForm->getTitle() . ' - ' . $headBlock->getDefaultTitle());
+            }
+
+            if ($this->_getCheckout()->getCustomerDefaultShippingAddress()) {
+                $addressForm->setBackUrl($this->_url->getUrl('*/checkout/addresses'));
+            } else {
+                $addressForm->setBackUrl($this->_url->getUrl('*/cart/'));
+            }
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/SaveBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/SaveBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c845886ffff657d16cbfa4048b9c31c2ecb87d2
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/SaveBilling.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class SaveBilling extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($addressId = $this->getRequest()->getParam('id')) {
+            $this->_objectManager->create(
+                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
+            )->setQuoteCustomerBillingAddress(
+                $addressId
+            );
+        }
+        $this->_redirect('*/checkout/overview');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/SelectBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/SelectBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..322526a407cc06f985471434dcfc5b0c86823ad9
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/SelectBilling.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class SelectBilling extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(
+            \Magento\Multishipping\Model\Checkout\Type\Multishipping\State::STEP_BILLING
+        );
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/SetBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/SetBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..5aa5e7b0b9188c97251ff95b0c435a679c33208e
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/SetBilling.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+class SetBilling extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($addressId = $this->getRequest()->getParam('id')) {
+            $this->_objectManager->create(
+                'Magento\Multishipping\Model\Checkout\Type\Multishipping'
+            )->setQuoteCustomerBillingAddress(
+                $addressId
+            );
+        }
+        $this->_redirect('*/checkout/billing');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Address/ShippingSaved.php b/app/code/Magento/Multishipping/Controller/Checkout/Address/ShippingSaved.php
new file mode 100644
index 0000000000000000000000000000000000000000..d458550ebcec0573ccae78dd81b77c84a2389eb1
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Address/ShippingSaved.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout\Address;
+
+use Magento\Framework\App\Action\Context;
+use Magento\Customer\Service\V1\CustomerAddressServiceInterface;
+
+class ShippingSaved extends \Magento\Multishipping\Controller\Checkout\Address
+{
+    /**
+     * @var CustomerAddressServiceInterface
+     */
+    protected $_customerAddressService;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param Context $context
+     * @param CustomerAddressServiceInterface $customerAddressService
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        CustomerAddressServiceInterface $customerAddressService
+    ) {
+        $this->_customerAddressService = $customerAddressService;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        /**
+         * if we create first address we need reset emd init checkout
+         */
+        $customerId = $this->_getCheckout()->getCustomer()->getId();
+        if (count($this->_customerAddressService->getAddresses($customerId)) == 1) {
+            $this->_getCheckout()->reset();
+        }
+        $this->_redirect('*/checkout/addresses');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Addresses.php b/app/code/Magento/Multishipping/Controller/Checkout/Addresses.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa635d292fe5fb9b52da060104213187c75ed879
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Addresses.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class Addresses extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout select address page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // If customer do not have addresses
+        if (!$this->_getCheckout()->getCustomerDefaultShippingAddress()) {
+            $this->_redirect('*/checkout_address/newShipping');
+            return;
+        }
+
+        $this->_getState()->unsCompleteStep(State::STEP_SHIPPING);
+
+        $this->_getState()->setActiveStep(State::STEP_SELECT_ADDRESSES);
+        if (!$this->_getCheckout()->validateMinimumAmount()) {
+            $message = $this->_getCheckout()->getMinimumAmountDescription();
+            $this->messageManager->addNotice($message);
+        }
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/AddressesPost.php b/app/code/Magento/Multishipping/Controller/Checkout/AddressesPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..b93449ce737b3ead39ca33d95fd5132c46d1eee4
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/AddressesPost.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class AddressesPost extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout process posted addresses
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_getCheckout()->getCustomerDefaultShippingAddress()) {
+            $this->_redirect('*/checkout_address/newShipping');
+            return;
+        }
+        try {
+            if ($this->getRequest()->getParam('continue', false)) {
+                $this->_getCheckout()->setCollectRatesFlag(true);
+                $this->_getState()->setActiveStep(State::STEP_SHIPPING);
+                $this->_getState()->setCompleteStep(State::STEP_SELECT_ADDRESSES);
+                $this->_redirect('*/*/shipping');
+            } elseif ($this->getRequest()->getParam('new_address')) {
+                $this->_redirect('*/checkout_address/newShipping');
+            } else {
+                $this->_redirect('*/*/addresses');
+            }
+            if ($shipToInfo = $this->getRequest()->getPost('ship')) {
+                $this->_getCheckout()->setShippingItemsInformation($shipToInfo);
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/addresses');
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Data saving problem'));
+            $this->_redirect('*/*/addresses');
+        }
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/BackToAddresses.php b/app/code/Magento/Multishipping/Controller/Checkout/BackToAddresses.php
new file mode 100644
index 0000000000000000000000000000000000000000..60473ac14e8395e66c7e468c6ad40298f7db2833
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/BackToAddresses.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class BackToAddresses extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(State::STEP_SELECT_ADDRESSES);
+        $this->_getState()->unsCompleteStep(State::STEP_SHIPPING);
+        $this->_redirect('*/*/addresses');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/BackToBilling.php b/app/code/Magento/Multishipping/Controller/Checkout/BackToBilling.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dc6bf0d4c075cfc91c3f1c322216da1d50a6c9b
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/BackToBilling.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class BackToBilling extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Back to billing action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(State::STEP_BILLING);
+        $this->_getState()->unsCompleteStep(State::STEP_OVERVIEW);
+        $this->_redirect('*/*/billing');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/BackToShipping.php b/app/code/Magento/Multishipping/Controller/Checkout/BackToShipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2abe8182ac5e7f64e903b08895e885a90aff6eb
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/BackToShipping.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class BackToShipping extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getState()->setActiveStep(State::STEP_SHIPPING);
+        $this->_getState()->unsCompleteStep(State::STEP_BILLING);
+        $this->_redirect('*/*/shipping');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Billing.php b/app/code/Magento/Multishipping/Controller/Checkout/Billing.php
new file mode 100644
index 0000000000000000000000000000000000000000..04e5e04404fa1c43350633f256bd5421ed9654f4
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Billing.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+use Magento\Framework\App\ResponseInterface;
+
+class Billing extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Validation of selecting of billing address
+     *
+     * @return boolean
+     */
+    protected function _validateBilling()
+    {
+        if (!$this->_getCheckout()->getQuote()->getBillingAddress()->getFirstname()) {
+            $this->_redirect('*/checkout_address/selectBilling');
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Multishipping checkout billing information page
+     *
+     * @return void|ResponseInterface
+     */
+    public function execute()
+    {
+        if (!$this->_validateBilling()) {
+            return;
+        }
+
+        if (!$this->_validateMinimumAmount()) {
+            return;
+        }
+
+        if (!$this->_getState()->getCompleteStep(State::STEP_SHIPPING)) {
+            return $this->_redirect('*/*/shipping');
+        }
+
+        $this->_getState()->setActiveStep(State::STEP_BILLING);
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Index.php b/app/code/Magento/Multishipping/Controller/Checkout/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec863816d731de873b10075201622449e401e819
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class Index extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Index action of Multishipping checkout
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getCheckoutSession()->setCartWasUpdated(false);
+        $this->_redirect('*/*/addresses');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Login.php b/app/code/Magento/Multishipping/Controller/Checkout/Login.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ac6c9c7ad8755f68dd4eebf3af9e01079eb678e
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Login.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class Login extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout login page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+            $this->_redirect('*/*/');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        // set account create url
+        $loginForm = $this->_view->getLayout()->getBlock('customer.new');
+        if ($loginForm) {
+            $loginForm->setCreateAccountUrl($this->_getHelper()->getMSRegisterUrl());
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Overview.php b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab52c74db2e5a241c333b219b8677d85270fcdad
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Overview.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class Overview extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout place order page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateMinimumAmount()) {
+            return;
+        }
+
+        $this->_getState()->setActiveStep(State::STEP_OVERVIEW);
+
+        try {
+            $payment = $this->getRequest()->getPost('payment', array());
+            $payment['checks'] = array(
+                \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
+                \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
+                \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
+                \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
+            );
+            $this->_getCheckout()->setPaymentMethod($payment);
+
+            $this->_getState()->setCompleteStep(State::STEP_BILLING);
+
+            $this->_view->loadLayout();
+            $this->_view->getLayout()->initMessages();
+            $this->_view->renderLayout();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/billing');
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addException($e, __('We cannot open the overview page.'));
+            $this->_redirect('*/*/billing');
+        }
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f803c9a62abf8c15c49c9a8a72f1319adc7f02f
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/OverviewPost.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class OverviewPost extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Overview action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateMinimumAmount()) {
+            return;
+        }
+
+        try {
+            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
+            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', array())))) {
+                $this->messageManager->addError(
+                    __('Please agree to all Terms and Conditions before placing the order.')
+                );
+                $this->_redirect('*/*/billing');
+                return;
+            }
+
+            $payment = $this->getRequest()->getPost('payment');
+            $paymentInstance = $this->_getCheckout()->getQuote()->getPayment();
+            if (isset($payment['cc_number'])) {
+                $paymentInstance->setCcNumber($payment['cc_number']);
+            }
+            if (isset($payment['cc_cid'])) {
+                $paymentInstance->setCcCid($payment['cc_cid']);
+            }
+            $this->_getCheckout()->createOrders();
+            $this->_getState()->setActiveStep(State::STEP_SUCCESS);
+            $this->_getState()->setCompleteStep(State::STEP_OVERVIEW);
+            $this->_getCheckout()->getCheckoutSession()->clearQuote();
+            $this->_getCheckout()->getCheckoutSession()->setDisplaySuccess(true);
+            $this->_redirect('*/*/success');
+        } catch (\Magento\Payment\Model\Info\Exception $e) {
+            $message = $e->getMessage();
+            if (!empty($message)) {
+                $this->messageManager->addError($message);
+            }
+            $this->_redirect('*/*/billing');
+        } catch (\Magento\Checkout\Exception $e) {
+            $this->_objectManager->get(
+                'Magento\Checkout\Helper\Data'
+            )->sendPaymentFailedEmail(
+                $this->_getCheckout()->getQuote(),
+                $e->getMessage(),
+                'multi-shipping'
+            );
+            $this->_getCheckout()->getCheckoutSession()->clearQuote();
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/cart');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->_objectManager->get(
+                'Magento\Checkout\Helper\Data'
+            )->sendPaymentFailedEmail(
+                $this->_getCheckout()->getQuote(),
+                $e->getMessage(),
+                'multi-shipping'
+            );
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/billing');
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_objectManager->get(
+                'Magento\Checkout\Helper\Data'
+            )->sendPaymentFailedEmail(
+                $this->_getCheckout()->getQuote(),
+                $e->getMessage(),
+                'multi-shipping'
+            );
+            $this->messageManager->addError(__('Order place error'));
+            $this->_redirect('*/*/billing');
+        }
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php b/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..61e08ac15e6a08ad3f9b72224ba4ce0d8c9c27ca
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Plugin.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class Plugin
+{
+    /**
+     * @var \Magento\Checkout\Model\Cart
+     */
+    protected $cart;
+
+    /**
+     * @param \Magento\Checkout\Model\Cart $cart
+     */
+    public function __construct(\Magento\Checkout\Model\Cart $cart)
+    {
+        $this->cart = $cart;
+    }
+
+    /**
+     * Disable multishipping
+     *
+     * @param \Magento\Framework\App\Action\Action $subject
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function beforeExecute(\Magento\Framework\App\Action\Action $subject)
+    {
+        $this->cart->getQuote()->setIsMultiShipping(0);
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Register.php b/app/code/Magento/Multishipping/Controller/Checkout/Register.php
new file mode 100644
index 0000000000000000000000000000000000000000..8836c951583e42f14e71fc0b554f55bcbb2bc32d
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Register.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class Register extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout login page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+            $this->getResponse()->setRedirect($this->_getHelper()->getMSCheckoutUrl());
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $registerForm = $this->_view->getLayout()->getBlock('customer_form_register');
+        if ($registerForm) {
+            $registerForm->setShowAddressFields(
+                true
+            )->setBackUrl(
+                $this->_getHelper()->getMSLoginUrl()
+            )->setSuccessUrl(
+                $this->_getHelper()->getMSShippingAddressSavedUrl()
+            )->setErrorUrl(
+                $this->_url->getCurrentUrl()
+            );
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/RemoveItem.php b/app/code/Magento/Multishipping/Controller/Checkout/RemoveItem.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0d959ad24009c49283b3bb6de0d00212e7264de
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/RemoveItem.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class RemoveItem extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout remove item action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $itemId = $this->getRequest()->getParam('id');
+        $addressId = $this->getRequest()->getParam('address');
+        if ($addressId && $itemId) {
+            $this->_getCheckout()->setCollectRatesFlag(true);
+            $this->_getCheckout()->removeAddressItem($addressId, $itemId);
+        }
+        $this->_redirect('*/*/addresses');
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Shipping.php b/app/code/Magento/Multishipping/Controller/Checkout/Shipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4f25678554677fa19041da330674144f134280b
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Shipping.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+use Magento\Framework\App\ResponseInterface;
+
+class Shipping extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout shipping information page
+     *
+     * @return  ResponseInterface|void
+     */
+    public function execute()
+    {
+        if (!$this->_validateMinimumAmount()) {
+            return;
+        }
+
+        if (!$this->_getState()->getCompleteStep(State::STEP_SELECT_ADDRESSES)) {
+            return $this->_redirect('*/*/addresses');
+        }
+
+        $this->_getState()->setActiveStep(State::STEP_SHIPPING);
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/ShippingPost.php b/app/code/Magento/Multishipping/Controller/Checkout/ShippingPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..8853df01311d9994cf8709e9b8492eb7eede652d
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/ShippingPost.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class ShippingPost extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $shippingMethods = $this->getRequest()->getPost('shipping_method');
+        try {
+            $this->_eventManager->dispatch(
+                'checkout_controller_multishipping_shipping_post',
+                array('request' => $this->getRequest(), 'quote' => $this->_getCheckout()->getQuote())
+            );
+            $this->_getCheckout()->setShippingMethods($shippingMethods);
+            $this->_getState()->setActiveStep(State::STEP_BILLING);
+            $this->_getState()->setCompleteStep(State::STEP_SHIPPING);
+            $this->_redirect('*/*/billing');
+        } catch (\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/shipping');
+        }
+    }
+}
diff --git a/app/code/Magento/Multishipping/Controller/Checkout/Success.php b/app/code/Magento/Multishipping/Controller/Checkout/Success.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ecfe9ed3b03efeaa9a766aa2b4557fa0362e4c8
--- /dev/null
+++ b/app/code/Magento/Multishipping/Controller/Checkout/Success.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+use \Magento\Multishipping\Model\Checkout\Type\Multishipping\State;
+
+class Success extends \Magento\Multishipping\Controller\Checkout
+{
+    /**
+     * Multishipping checkout success page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_getState()->getCompleteStep(State::STEP_OVERVIEW)) {
+            $this->_redirect('*/*/addresses');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $ids = $this->_getCheckout()->getOrderIds();
+        $this->_eventManager->dispatch('multishipping_checkout_controller_success_action', array('order_ids' => $ids));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Multishipping/etc/frontend/di.xml b/app/code/Magento/Multishipping/etc/frontend/di.xml
index c3a8ed9b477cc48957c9b406f63de9ce11f472e8..53d6298f1ea2ea5a47facdacccb090e93186b2cd 100644
--- a/app/code/Magento/Multishipping/etc/frontend/di.xml
+++ b/app/code/Magento/Multishipping/etc/frontend/di.xml
@@ -49,4 +49,13 @@
             <argument name="paymentSpecification" xsi:type="object">multishippingPaymentSpecification</argument>
         </arguments>
     </type>
+    <type name="Magento\Checkout\Controller\Cart\Add">
+        <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" />
+    </type>
+    <type name="Magento\Checkout\Controller\Cart\UpdatePost">
+        <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" />
+    </type>
+    <type name="Magento\Checkout\Controller\Onepage\Index">
+        <plugin name="multishipping_disabler" type="Magento\Multishipping\Controller\Checkout\Plugin" sortOrder="50" />
+    </type>
 </config>
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Problem.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem.php
index 6f5c6ad9b9b72c624c5b304b9a0845d2d6ea8e00..bda3479bf897a8618ac8bec4ab6e7f94ad525e0a 100644
--- a/app/code/Magento/Newsletter/Controller/Adminhtml/Problem.php
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem.php
@@ -28,68 +28,6 @@ namespace Magento\Newsletter\Controller\Adminhtml;
  */
 class Problem extends \Magento\Backend\App\Action
 {
-    /**
-     * Newsletter problems report page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Newsletter Problems Report'));
-
-        if ($this->getRequest()->getQuery('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-
-        $this->_view->getLayout()->getMessagesBlock()->setMessages($this->messageManager->getMessages(true));
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_problem');
-        $this->_addBreadcrumb(__('Newsletter Problem Reports'), __('Newsletter Problem Reports'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Newsletter problems grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        if ($this->getRequest()->getParam('_unsubscribe')) {
-            $problems = (array)$this->getRequest()->getParam('problem', array());
-            if (count($problems) > 0) {
-                $collection = $this->_objectManager->create('Magento\Newsletter\Model\Resource\Problem\Collection');
-                $collection->addSubscriberInfo()->addFieldToFilter(
-                    $collection->getResource()->getIdFieldName(),
-                    array('in' => $problems)
-                )->load();
-
-                $collection->walk('unsubscribe');
-            }
-
-            $this->messageManager->addSuccess(__('We unsubscribed the people you identified.'));
-        }
-
-        if ($this->getRequest()->getParam('_delete')) {
-            $problems = (array)$this->getRequest()->getParam('problem', array());
-            if (count($problems) > 0) {
-                $collection = $this->_objectManager->create('Magento\Newsletter\Model\Resource\Problem\Collection');
-                $collection->addFieldToFilter(
-                    $collection->getResource()->getIdFieldName(),
-                    array('in' => $problems)
-                )->load();
-                $collection->walk('delete');
-            }
-
-            $this->messageManager->addSuccess(__('The problems you identified have been deleted.'));
-        }
-        $this->_view->getLayout()->getMessagesBlock()->setMessages($this->messageManager->getMessages(true));
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
 
     /**
      * Check if user has enough privileges
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Grid.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..304d4dc3cfb30e006ff38151dd9d5ff21ac2c871
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Grid.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Problem;
+
+class Grid extends \Magento\Newsletter\Controller\Adminhtml\Problem
+{
+    /**
+     * Newsletter problems grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('_unsubscribe')) {
+            $problems = (array)$this->getRequest()->getParam('problem', array());
+            if (count($problems) > 0) {
+                $collection = $this->_objectManager->create('Magento\Newsletter\Model\Resource\Problem\Collection');
+                $collection->addSubscriberInfo()->addFieldToFilter(
+                    $collection->getResource()->getIdFieldName(),
+                    array('in' => $problems)
+                )->load();
+
+                $collection->walk('unsubscribe');
+            }
+
+            $this->messageManager->addSuccess(__('We unsubscribed the people you identified.'));
+        }
+
+        if ($this->getRequest()->getParam('_delete')) {
+            $problems = (array)$this->getRequest()->getParam('problem', array());
+            if (count($problems) > 0) {
+                $collection = $this->_objectManager->create('Magento\Newsletter\Model\Resource\Problem\Collection');
+                $collection->addFieldToFilter(
+                    $collection->getResource()->getIdFieldName(),
+                    array('in' => $problems)
+                )->load();
+                $collection->walk('delete');
+            }
+
+            $this->messageManager->addSuccess(__('The problems you identified have been deleted.'));
+        }
+        $this->_view->getLayout()->getMessagesBlock()->setMessages($this->messageManager->getMessages(true));
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Index.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f37b3f4d1fb39353f4d728a8d90eefbf53e32acb
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Problem/Index.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Problem;
+
+class Index extends \Magento\Newsletter\Controller\Adminhtml\Problem
+{
+    /**
+     * Newsletter problems report page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Newsletter Problems Report'));
+
+        if ($this->getRequest()->getQuery('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+
+        $this->_view->getLayout()->getMessagesBlock()->setMessages($this->messageManager->getMessages(true));
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_problem');
+        $this->_addBreadcrumb(__('Newsletter Problem Reports'), __('Newsletter Problem Reports'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue.php
index f1294d0221f2d8e00315db66793593ff10592711..0a772c09ed8aa80e72b2a54f6a218338d229bd6d 100644
--- a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue.php
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue.php
@@ -31,333 +31,6 @@ namespace Magento\Newsletter\Controller\Adminhtml;
 
 class Queue extends \Magento\Backend\App\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
-    /**
-     * Queue list action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Newsletter Queue'));
-
-        if ($this->getRequest()->getQuery('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_queue');
-
-        $this->_addBreadcrumb(__('Newsletter Queue'), __('Newsletter Queue'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Drop Newsletter queue template
-     *
-     * @return void
-     */
-    public function dropAction()
-    {
-        $this->_view->loadLayout('newsletter_queue_preview_popup');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Preview Newsletter queue template
-     *
-     * @return void
-     */
-    public function previewAction()
-    {
-        $this->_view->loadLayout();
-        $data = $this->getRequest()->getParams();
-        if (empty($data) || !isset($data['id'])) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        // set default value for selected store
-        $data['preview_store_id'] = $this->_objectManager->get(
-            'Magento\Store\Model\StoreManager'
-        )->getDefaultStoreView()->getId();
-
-        $this->_view->getLayout()->getBlock('preview_form')->setFormData($data);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Queue list Ajax action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Start Newsletter queue
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        $queue = $this->_objectManager->create(
-            'Magento\Newsletter\Model\Queue'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-        if ($queue->getId()) {
-            if (!in_array(
-                $queue->getQueueStatus(),
-                array(\Magento\Newsletter\Model\Queue::STATUS_NEVER, \Magento\Newsletter\Model\Queue::STATUS_PAUSE)
-            )
-            ) {
-                $this->_redirect('*/*');
-                return;
-            }
-
-            $queue->setQueueStartAt(
-                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
-            )->setQueueStatus(
-                \Magento\Newsletter\Model\Queue::STATUS_SENDING
-            )->save();
-        }
-
-        $this->_redirect('*/*');
-    }
-
-    /**
-     * Pause Newsletter queue
-     *
-     * @return void
-     */
-    public function pauseAction()
-    {
-        $queue = $this->_objectManager->get(
-            'Magento\Newsletter\Model\Queue'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_SENDING))) {
-            $this->_redirect('*/*');
-            return;
-        }
-
-        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_PAUSE);
-        $queue->save();
-
-        $this->_redirect('*/*');
-    }
-
-    /**
-     * Resume Newsletter queue
-     *
-     * @return void
-     */
-    public function resumeAction()
-    {
-        $queue = $this->_objectManager->get(
-            'Magento\Newsletter\Model\Queue'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_PAUSE))) {
-            $this->_redirect('*/*');
-            return;
-        }
-
-        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_SENDING);
-        $queue->save();
-
-        $this->_redirect('*/*');
-    }
-
-    /**
-     * Cancel Newsletter queue
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $queue = $this->_objectManager->get(
-            'Magento\Newsletter\Model\Queue'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_SENDING))) {
-            $this->_redirect('*/*');
-            return;
-        }
-
-        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_CANCEL);
-        $queue->save();
-
-        $this->_redirect('*/*');
-    }
-
-    /**
-     * Send Newsletter queue
-     *
-     * @return void
-     */
-    public function sendingAction()
-    {
-        // Todo: put it somewhere in config!
-        $countOfQueue = 3;
-        $countOfSubscritions = 20;
-
-        $collection = $this->_objectManager->create(
-            'Magento\Newsletter\Model\Resource\Queue\Collection'
-        )->setPageSize(
-            $countOfQueue
-        )->setCurPage(
-            1
-        )->addOnlyForSendingFilter()->load();
-
-        $collection->walk('sendPerSubscriber', array($countOfSubscritions));
-    }
-
-    /**
-     * Edit Newsletter queue
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Newsletter Queue'));
-
-        $this->_coreRegistry->register('current_queue', $this->_objectManager->get('Magento\Newsletter\Model\Queue'));
-
-        $id = $this->getRequest()->getParam('id');
-        $templateId = $this->getRequest()->getParam('template_id');
-
-        if ($id) {
-            $queue = $this->_coreRegistry->registry('current_queue')->load($id);
-        } elseif ($templateId) {
-            $template = $this->_objectManager->create('Magento\Newsletter\Model\Template')->load($templateId);
-            $queue = $this->_coreRegistry->registry('current_queue')->setTemplateId($template->getId());
-        }
-
-        $this->_title->add(__('Edit Queue'));
-
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_queue');
-
-        $this->_addBreadcrumb(__('Newsletter Queue'), __('Newsletter Queue'), $this->getUrl('*/*'));
-        $this->_addBreadcrumb(__('Edit Queue'), __('Edit Queue'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save Newsletter queue
-     *
-     * @throws \Magento\Framework\Model\Exception
-     * @return void
-     */
-    public function saveAction()
-    {
-        try {
-            /* @var $queue \Magento\Newsletter\Model\Queue */
-            $queue = $this->_objectManager->create('Magento\Newsletter\Model\Queue');
-
-            $templateId = $this->getRequest()->getParam('template_id');
-            if ($templateId) {
-                /* @var $template \Magento\Newsletter\Model\Template */
-                $template = $this->_objectManager->create('Magento\Newsletter\Model\Template')->load($templateId);
-
-                if (!$template->getId() || $template->getIsSystem()) {
-                    throw new \Magento\Framework\Model\Exception(__('Please correct the newsletter template and try again.'));
-                }
-
-                $queue->setTemplateId(
-                    $template->getId()
-                )->setQueueStatus(
-                    \Magento\Newsletter\Model\Queue::STATUS_NEVER
-                );
-            } else {
-                $queue->load($this->getRequest()->getParam('id'));
-            }
-
-            if (!in_array(
-                $queue->getQueueStatus(),
-                array(\Magento\Newsletter\Model\Queue::STATUS_NEVER, \Magento\Newsletter\Model\Queue::STATUS_PAUSE)
-            )
-            ) {
-                $this->_redirect('*/*');
-                return;
-            }
-
-            if ($queue->getQueueStatus() == \Magento\Newsletter\Model\Queue::STATUS_NEVER) {
-                $queue->setQueueStartAtByString($this->getRequest()->getParam('start_at'));
-            }
-
-            $queue->setStores(
-                $this->getRequest()->getParam('stores', array())
-            )->setNewsletterSubject(
-                $this->getRequest()->getParam('subject')
-            )->setNewsletterSenderName(
-                $this->getRequest()->getParam('sender_name')
-            )->setNewsletterSenderEmail(
-                $this->getRequest()->getParam('sender_email')
-            )->setNewsletterText(
-                $this->getRequest()->getParam('text')
-            )->setNewsletterStyles(
-                $this->getRequest()->getParam('styles')
-            );
-
-            if ($queue->getQueueStatus() == \Magento\Newsletter\Model\Queue::STATUS_PAUSE
-                && $this->getRequest()->getParam(
-                    '_resume',
-                    false
-                )
-            ) {
-                $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_SENDING);
-            }
-
-            $queue->save();
-
-            $this->messageManager->addSuccess(__('The newsletter queue has been saved.'));
-            $this->_getSession()->setFormData(false);
-
-            $this->_redirect('*/*');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $id = $this->getRequest()->getParam('id');
-            if ($id) {
-                $this->_redirect('*/*/edit', array('id' => $id));
-            } else {
-                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            }
-        }
-    }
-
     /**
      * Check if user has enough privileges
      *
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Cancel.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..7190698ce628f750c70d27e339c31bdeeeeeb0b8
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Cancel.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Cancel extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Cancel Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $queue = $this->_objectManager->get(
+            'Magento\Newsletter\Model\Queue'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_SENDING))) {
+            $this->_redirect('*/*');
+            return;
+        }
+
+        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_CANCEL);
+        $queue->save();
+
+        $this->_redirect('*/*');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Drop.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Drop.php
new file mode 100644
index 0000000000000000000000000000000000000000..520b4ab6d6fab57d238169aeaee7aea29af2fa84
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Drop.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Drop extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Drop Newsletter queue template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout('newsletter_queue_preview_popup');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Edit.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a3b45af69a4a4552478c8bd8a9a47bd408102b0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Edit.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Edit extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Edit Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Newsletter Queue'));
+
+        $this->_coreRegistry->register('current_queue', $this->_objectManager->get('Magento\Newsletter\Model\Queue'));
+
+        $id = $this->getRequest()->getParam('id');
+        $templateId = $this->getRequest()->getParam('template_id');
+
+        if ($id) {
+            $queue = $this->_coreRegistry->registry('current_queue')->load($id);
+        } elseif ($templateId) {
+            $template = $this->_objectManager->create('Magento\Newsletter\Model\Template')->load($templateId);
+            $queue = $this->_coreRegistry->registry('current_queue')->setTemplateId($template->getId());
+        }
+
+        $this->_title->add(__('Edit Queue'));
+
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_queue');
+
+        $this->_addBreadcrumb(__('Newsletter Queue'), __('Newsletter Queue'), $this->getUrl('*/*'));
+        $this->_addBreadcrumb(__('Edit Queue'), __('Edit Queue'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Grid.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..6dea0d54fc9c17bf15880ed9404c04b10ceb7a8d
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Grid extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Queue list Ajax action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Index.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..01fe41c9dd11b85ee6e7a8481d1488a4c23fa7f9
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Index.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Index extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Queue list action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Newsletter Queue'));
+
+        if ($this->getRequest()->getQuery('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_queue');
+
+        $this->_addBreadcrumb(__('Newsletter Queue'), __('Newsletter Queue'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Pause.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Pause.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5624bfd8a82c684a59a0a869bf60262d89542d0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Pause.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Pause extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Pause Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $queue = $this->_objectManager->get(
+            'Magento\Newsletter\Model\Queue'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_SENDING))) {
+            $this->_redirect('*/*');
+            return;
+        }
+
+        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_PAUSE);
+        $queue->save();
+
+        $this->_redirect('*/*');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Preview.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Preview.php
new file mode 100644
index 0000000000000000000000000000000000000000..156c8116a8aace55bd41ba135e4f8df6346173d5
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Preview.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Preview extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Preview Newsletter queue template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $data = $this->getRequest()->getParams();
+        if (empty($data) || !isset($data['id'])) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        // set default value for selected store
+        $data['preview_store_id'] = $this->_objectManager->get(
+            'Magento\Store\Model\StoreManager'
+        )->getDefaultStoreView()->getId();
+
+        $this->_view->getLayout()->getBlock('preview_form')->setFormData($data);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Resume.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Resume.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ed41fd06ec7dee9defa6cb1b3cafa89862d34d5
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Resume.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Resume extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Resume Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $queue = $this->_objectManager->get(
+            'Magento\Newsletter\Model\Queue'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!in_array($queue->getQueueStatus(), array(\Magento\Newsletter\Model\Queue::STATUS_PAUSE))) {
+            $this->_redirect('*/*');
+            return;
+        }
+
+        $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_SENDING);
+        $queue->save();
+
+        $this->_redirect('*/*');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Save.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..152b45db868e8269aa9efd9ab18032edfe48e045
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Save.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Save extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Save Newsletter queue
+     *
+     * @throws \Magento\Framework\Model\Exception
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            /* @var $queue \Magento\Newsletter\Model\Queue */
+            $queue = $this->_objectManager->create('Magento\Newsletter\Model\Queue');
+
+            $templateId = $this->getRequest()->getParam('template_id');
+            if ($templateId) {
+                /* @var $template \Magento\Newsletter\Model\Template */
+                $template = $this->_objectManager->create('Magento\Newsletter\Model\Template')->load($templateId);
+
+                if (!$template->getId() || $template->getIsSystem()) {
+                    throw new \Magento\Framework\Model\Exception(__('Please correct the newsletter template and try again.'));
+                }
+
+                $queue->setTemplateId(
+                    $template->getId()
+                )->setQueueStatus(
+                    \Magento\Newsletter\Model\Queue::STATUS_NEVER
+                );
+            } else {
+                $queue->load($this->getRequest()->getParam('id'));
+            }
+
+            if (!in_array(
+                $queue->getQueueStatus(),
+                array(\Magento\Newsletter\Model\Queue::STATUS_NEVER, \Magento\Newsletter\Model\Queue::STATUS_PAUSE)
+            )
+            ) {
+                $this->_redirect('*/*');
+                return;
+            }
+
+            if ($queue->getQueueStatus() == \Magento\Newsletter\Model\Queue::STATUS_NEVER) {
+                $queue->setQueueStartAtByString($this->getRequest()->getParam('start_at'));
+            }
+
+            $queue->setStores(
+                $this->getRequest()->getParam('stores', array())
+            )->setNewsletterSubject(
+                $this->getRequest()->getParam('subject')
+            )->setNewsletterSenderName(
+                $this->getRequest()->getParam('sender_name')
+            )->setNewsletterSenderEmail(
+                $this->getRequest()->getParam('sender_email')
+            )->setNewsletterText(
+                $this->getRequest()->getParam('text')
+            )->setNewsletterStyles(
+                $this->getRequest()->getParam('styles')
+            );
+
+            if ($queue->getQueueStatus() == \Magento\Newsletter\Model\Queue::STATUS_PAUSE
+                && $this->getRequest()->getParam(
+                    '_resume',
+                    false
+                )
+            ) {
+                $queue->setQueueStatus(\Magento\Newsletter\Model\Queue::STATUS_SENDING);
+            }
+
+            $queue->save();
+
+            $this->messageManager->addSuccess(__('The newsletter queue has been saved.'));
+            $this->_getSession()->setFormData(false);
+
+            $this->_redirect('*/*');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $id = $this->getRequest()->getParam('id');
+            if ($id) {
+                $this->_redirect('*/*/edit', array('id' => $id));
+            } else {
+                $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Sending.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Sending.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a964fd4d0511c4829c7d6229cf2e03a549e26eb
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Sending.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Sending extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Send Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // Todo: put it somewhere in config!
+        $countOfQueue = 3;
+        $countOfSubscritions = 20;
+
+        $collection = $this->_objectManager->create(
+            'Magento\Newsletter\Model\Resource\Queue\Collection'
+        )->setPageSize(
+            $countOfQueue
+        )->setCurPage(
+            1
+        )->addOnlyForSendingFilter()->load();
+
+        $collection->walk('sendPerSubscriber', array($countOfSubscritions));
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Start.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d824dcc99878b1d75927ad077700acb073e84a0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Queue/Start.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Queue;
+
+class Start extends \Magento\Newsletter\Controller\Adminhtml\Queue
+{
+    /**
+     * Start Newsletter queue
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $queue = $this->_objectManager->create(
+            'Magento\Newsletter\Model\Queue'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+        if ($queue->getId()) {
+            if (!in_array(
+                $queue->getQueueStatus(),
+                array(\Magento\Newsletter\Model\Queue::STATUS_NEVER, \Magento\Newsletter\Model\Queue::STATUS_PAUSE)
+            )
+            ) {
+                $this->_redirect('*/*');
+                return;
+            }
+
+            $queue->setQueueStartAt(
+                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
+            )->setQueueStatus(
+                \Magento\Newsletter\Model\Queue::STATUS_SENDING
+            )->save();
+        }
+
+        $this->_redirect('*/*');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber.php
index 1629ed1079efe7d8f64b3389ff9926e88b620df5..9fafe90c7f29389739b051b177f39dec3c478be5 100644
--- a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber.php
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber.php
@@ -23,8 +23,6 @@
  */
 namespace Magento\Newsletter\Controller\Adminhtml;
 
-use Magento\Framework\App\ResponseInterface;
-
 /**
  * Newsletter subscribers controller
  */
@@ -47,134 +45,6 @@ class Subscriber extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Newsletter subscribers page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Newsletter Subscribers'));
-
-        if ($this->getRequest()->getParam('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_subscriber');
-
-        $this->_addBreadcrumb(__('Newsletter'), __('Newsletter'));
-        $this->_addBreadcrumb(__('Subscribers'), __('Subscribers'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Managing newsletter grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export subscribers grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'subscribers.csv';
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.newslettrer.subscriber.grid', 'grid.export');
-
-        return $this->_fileFactory->create(
-            $fileName,
-            $content->getCsvFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export subscribers grid to XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportXmlAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'subscribers.xml';
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.newslettrer.subscriber.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $content->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Unsubscribe one or more subscribers action
-     *
-     * @return void
-     */
-    public function massUnsubscribeAction()
-    {
-        $subscribersIds = $this->getRequest()->getParam('subscriber');
-        if (!is_array($subscribersIds)) {
-            $this->messageManager->addError(__('Please select one or more subscribers.'));
-        } else {
-            try {
-                foreach ($subscribersIds as $subscriberId) {
-                    $subscriber = $this->_objectManager->create(
-                        'Magento\Newsletter\Model\Subscriber'
-                    )->load(
-                        $subscriberId
-                    );
-                    $subscriber->unsubscribe();
-                }
-                $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', count($subscribersIds)));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-
-        $this->_redirect('*/*/index');
-    }
-
-    /**
-     * Delete one or more subscribers action
-     *
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $subscribersIds = $this->getRequest()->getParam('subscriber');
-        if (!is_array($subscribersIds)) {
-            $this->messageManager->addError(__('Please select one or more subscribers.'));
-        } else {
-            try {
-                foreach ($subscribersIds as $subscriberId) {
-                    $subscriber = $this->_objectManager->create(
-                        'Magento\Newsletter\Model\Subscriber'
-                    )->load(
-                        $subscriberId
-                    );
-                    $subscriber->delete();
-                }
-                $this->messageManager->addSuccess(__('Total of %1 record(s) were deleted', count($subscribersIds)));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-
-        $this->_redirect('*/*/index');
-    }
-
     /**
      * Check if user has enough privileges
      *
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportCsv.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..264b8c16f0c19ba8a41bca153a8e9f32ef1e84fd
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportCsv.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCsv extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Export subscribers grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'subscribers.csv';
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.newslettrer.subscriber.grid', 'grid.export');
+
+        return $this->_fileFactory->create(
+            $fileName,
+            $content->getCsvFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportXml.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportXml.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac4a4f970fc8dcaeced1b6bb04debe0278460c91
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/ExportXml.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportXml extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Export subscribers grid to XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'subscribers.xml';
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.newslettrer.subscriber.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $content->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Grid.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..2460f5432b94e4e7afde23b3175dd20d74a5a281
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+class Grid extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Managing newsletter grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Index.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..857182d30bca1be29855f5ce5b433034a31b42c6
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/Index.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+class Index extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Newsletter subscribers page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Newsletter Subscribers'));
+
+        if ($this->getRequest()->getParam('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_subscriber');
+
+        $this->_addBreadcrumb(__('Newsletter'), __('Newsletter'));
+        $this->_addBreadcrumb(__('Subscribers'), __('Subscribers'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassDelete.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..5950cdb17330b4d0b86e1b2024be8cf263b80ca0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassDelete.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+class MassDelete extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Delete one or more subscribers action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $subscribersIds = $this->getRequest()->getParam('subscriber');
+        if (!is_array($subscribersIds)) {
+            $this->messageManager->addError(__('Please select one or more subscribers.'));
+        } else {
+            try {
+                foreach ($subscribersIds as $subscriberId) {
+                    $subscriber = $this->_objectManager->create(
+                        'Magento\Newsletter\Model\Subscriber'
+                    )->load(
+                        $subscriberId
+                    );
+                    $subscriber->delete();
+                }
+                $this->messageManager->addSuccess(__('Total of %1 record(s) were deleted', count($subscribersIds)));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+
+        $this->_redirect('*/*/index');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassUnsubscribe.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassUnsubscribe.php
new file mode 100644
index 0000000000000000000000000000000000000000..37e2ee88c53a109bab876d46fbcf1ec9be3a1c8a
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Subscriber/MassUnsubscribe.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Subscriber;
+
+class MassUnsubscribe extends \Magento\Newsletter\Controller\Adminhtml\Subscriber
+{
+    /**
+     * Unsubscribe one or more subscribers action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $subscribersIds = $this->getRequest()->getParam('subscriber');
+        if (!is_array($subscribersIds)) {
+            $this->messageManager->addError(__('Please select one or more subscribers.'));
+        } else {
+            try {
+                foreach ($subscribersIds as $subscriberId) {
+                    $subscriber = $this->_objectManager->create(
+                        'Magento\Newsletter\Model\Subscriber'
+                    )->load(
+                        $subscriberId
+                    );
+                    $subscriber->unsubscribe();
+                }
+                $this->messageManager->addSuccess(__('A total of %1 record(s) were updated.', count($subscribersIds)));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+
+        $this->_redirect('*/*/index');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template.php
index 0810318a416f00833a4b080ae503f29bd9cb1ccc..c3b73c2ff2af8f46db63dc181b494e0e63dc3c51 100644
--- a/app/code/Magento/Newsletter/Controller/Adminhtml/Template.php
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template.php
@@ -30,23 +30,6 @@ namespace Magento\Newsletter\Controller\Adminhtml;
 
 class Template extends \Magento\Backend\App\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
     /**
      * Check is allowed access
      *
@@ -66,217 +49,4 @@ class Template extends \Magento\Backend\App\Action
     {
         return $this->_title->add(__('Newsletter Templates'));
     }
-
-    /**
-     * View Templates list
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_setTitle();
-
-        if ($this->getRequest()->getQuery('ajax')) {
-            $this->_forward('grid');
-            return;
-        }
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_template');
-        $this->_addBreadcrumb(__('Newsletter Templates'), __('Newsletter Templates'));
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Newsletter\Block\Adminhtml\Template', 'template')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * JSON Grid Action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout();
-        $grid = $this->_view->getLayout()->createBlock('Magento\Newsletter\Block\Adminhtml\Template\Grid')->toHtml();
-        $this->getResponse()->setBody($grid);
-    }
-
-    /**
-     * Create new Newsletter Template
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit Newsletter Template
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_setTitle();
-
-        $model = $this->_objectManager->create('Magento\Newsletter\Model\Template');
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            $model->load($id);
-        }
-
-        $this->_coreRegistry->register('_current_template', $model);
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Newsletter::newsletter_template');
-
-        if ($model->getId()) {
-            $breadcrumbTitle = __('Edit Template');
-            $breadcrumbLabel = $breadcrumbTitle;
-        } else {
-            $breadcrumbTitle = __('New Template');
-            $breadcrumbLabel = __('Create Newsletter Template');
-        }
-
-        $this->_title->add($model->getId() ? $model->getTemplateCode() : __('New Template'));
-
-        $this->_addBreadcrumb($breadcrumbLabel, $breadcrumbTitle);
-
-        // restore data
-        $values = $this->_getSession()->getData('newsletter_template_form_data', true);
-        if ($values) {
-            $model->addData($values);
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Drop Newsletter Template
-     *
-     * @return void
-     */
-    public function dropAction()
-    {
-        $this->_view->loadLayout('newsletter_template_preview_popup');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save Newsletter Template
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $request = $this->getRequest();
-        if (!$request->isPost()) {
-            $this->getResponse()->setRedirect($this->getUrl('*/template'));
-        }
-        $template = $this->_objectManager->create('Magento\Newsletter\Model\Template');
-
-        $id = (int)$request->getParam('id');
-        if ($id) {
-            $template->load($id);
-        }
-
-        try {
-            $template->addData(
-                $request->getParams()
-            )->setTemplateSubject(
-                $request->getParam('subject')
-            )->setTemplateCode(
-                $request->getParam('code')
-            )->setTemplateSenderEmail(
-                $request->getParam('sender_email')
-            )->setTemplateSenderName(
-                $request->getParam('sender_name')
-            )->setTemplateText(
-                $request->getParam('text')
-            )->setTemplateStyles(
-                $request->getParam('styles')
-            )->setModifiedAt(
-                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
-            );
-
-            if (!$template->getId()) {
-                $template->setTemplateType(\Magento\Newsletter\Model\Template::TYPE_HTML);
-            }
-            if ($this->getRequest()->getParam('_change_type_flag')) {
-                $template->setTemplateType(\Magento\Newsletter\Model\Template::TYPE_TEXT);
-                $template->setTemplateStyles('');
-            }
-            if ($this->getRequest()->getParam('_save_as_flag')) {
-                $template->setId(null);
-            }
-
-            $template->save();
-
-            $this->messageManager->addSuccess(__('The newsletter template has been saved.'));
-            $this->_getSession()->setFormData(false);
-
-            $this->_redirect('*/template');
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError(nl2br($e->getMessage()));
-            $this->_getSession()->setData('newsletter_template_form_data', $this->getRequest()->getParams());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('An error occurred while saving this template.'));
-            $this->_getSession()->setData('newsletter_template_form_data', $this->getRequest()->getParams());
-        }
-
-        $this->_forward('new');
-    }
-
-    /**
-     * Delete newsletter Template
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $template = $this->_objectManager->create(
-            'Magento\Newsletter\Model\Template'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-        if ($template->getId()) {
-            try {
-                $template->delete();
-                $this->messageManager->addSuccess(__('The newsletter template has been deleted.'));
-                $this->_getSession()->setFormData(false);
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while deleting this template.'));
-            }
-        }
-        $this->_redirect('*/template');
-    }
-
-    /**
-     * Preview Newsletter template
-     *
-     * @return void|$this
-     */
-    public function previewAction()
-    {
-        $this->_setTitle();
-        $this->_view->loadLayout();
-
-        $data = $this->getRequest()->getParams();
-        if (empty($data) || !isset($data['id'])) {
-            $this->_forward('noroute');
-            return $this;
-        }
-
-        // set default value for selected store
-        $data['preview_store_id'] = $this->_objectManager->get(
-            'Magento\Store\Model\StoreManager'
-        )->getDefaultStoreView()->getId();
-
-        $this->_view->getLayout()->getBlock('preview_form')->setFormData($data);
-        $this->_view->renderLayout();
-    }
 }
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Delete.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..5954e4934fe482a4e3cefdcb0379be00491b7f59
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Delete.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Delete extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Delete newsletter Template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $template = $this->_objectManager->create(
+            'Magento\Newsletter\Model\Template'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+        if ($template->getId()) {
+            try {
+                $template->delete();
+                $this->messageManager->addSuccess(__('The newsletter template has been deleted.'));
+                $this->_getSession()->setFormData(false);
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while deleting this template.'));
+            }
+        }
+        $this->_redirect('*/template');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Drop.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Drop.php
new file mode 100644
index 0000000000000000000000000000000000000000..0edccc941111c4f7bf7363b5e76c56b0fee86aef
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Drop.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Drop extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Drop Newsletter Template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout('newsletter_template_preview_popup');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Edit.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..95903f9640efcbda41cdac95bc60238c15d91bd0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Edit.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Edit extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Edit Newsletter Template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_setTitle();
+
+        $model = $this->_objectManager->create('Magento\Newsletter\Model\Template');
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            $model->load($id);
+        }
+
+        $this->_coreRegistry->register('_current_template', $model);
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_template');
+
+        if ($model->getId()) {
+            $breadcrumbTitle = __('Edit Template');
+            $breadcrumbLabel = $breadcrumbTitle;
+        } else {
+            $breadcrumbTitle = __('New Template');
+            $breadcrumbLabel = __('Create Newsletter Template');
+        }
+
+        $this->_title->add($model->getId() ? $model->getTemplateCode() : __('New Template'));
+
+        $this->_addBreadcrumb($breadcrumbLabel, $breadcrumbTitle);
+
+        // restore data
+        $values = $this->_getSession()->getData('newsletter_template_form_data', true);
+        if ($values) {
+            $model->addData($values);
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Grid.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f2d5af5a7b8ac846e2729936cc5f4d91563ba7c
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Grid.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Grid extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * JSON Grid Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $grid = $this->_view->getLayout()->createBlock('Magento\Newsletter\Block\Adminhtml\Template\Grid')->toHtml();
+        $this->getResponse()->setBody($grid);
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Index.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..4df42c385c674c6b498aa7fb7484958c53722658
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Index.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Index extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * View Templates list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_setTitle();
+
+        if ($this->getRequest()->getQuery('ajax')) {
+            $this->_forward('grid');
+            return;
+        }
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Newsletter::newsletter_template');
+        $this->_addBreadcrumb(__('Newsletter Templates'), __('Newsletter Templates'));
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Newsletter\Block\Adminhtml\Template', 'template')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/NewAction.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f56ec0a33c912b3d2f760e358ffe261c6c5bff1
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class NewAction extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Create new Newsletter Template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Preview.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Preview.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb4bd304f07334f4baa953035cf55601612b7a96
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Preview.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Preview extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Preview Newsletter template
+     *
+     * @return void|$this
+     */
+    public function execute()
+    {
+        $this->_setTitle();
+        $this->_view->loadLayout();
+
+        $data = $this->getRequest()->getParams();
+        if (empty($data) || !isset($data['id'])) {
+            $this->_forward('noroute');
+            return $this;
+        }
+
+        // set default value for selected store
+        $data['preview_store_id'] = $this->_objectManager->get(
+            'Magento\Store\Model\StoreManager'
+        )->getDefaultStoreView()->getId();
+
+        $this->_view->getLayout()->getBlock('preview_form')->setFormData($data);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Save.php b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..74dae74891af2c5f7dca0238ba8cd8b86717219a
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Adminhtml/Template/Save.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Adminhtml\Template;
+
+class Save extends \Magento\Newsletter\Controller\Adminhtml\Template
+{
+    /**
+     * Save Newsletter Template
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+        if (!$request->isPost()) {
+            $this->getResponse()->setRedirect($this->getUrl('*/template'));
+        }
+        $template = $this->_objectManager->create('Magento\Newsletter\Model\Template');
+
+        $id = (int)$request->getParam('id');
+        if ($id) {
+            $template->load($id);
+        }
+
+        try {
+            $template->addData(
+                $request->getParams()
+            )->setTemplateSubject(
+                $request->getParam('subject')
+            )->setTemplateCode(
+                $request->getParam('code')
+            )->setTemplateSenderEmail(
+                $request->getParam('sender_email')
+            )->setTemplateSenderName(
+                $request->getParam('sender_name')
+            )->setTemplateText(
+                $request->getParam('text')
+            )->setTemplateStyles(
+                $request->getParam('styles')
+            )->setModifiedAt(
+                $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->gmtDate()
+            );
+
+            if (!$template->getId()) {
+                $template->setTemplateType(\Magento\Newsletter\Model\Template::TYPE_HTML);
+            }
+            if ($this->getRequest()->getParam('_change_type_flag')) {
+                $template->setTemplateType(\Magento\Newsletter\Model\Template::TYPE_TEXT);
+                $template->setTemplateStyles('');
+            }
+            if ($this->getRequest()->getParam('_save_as_flag')) {
+                $template->setId(null);
+            }
+
+            $template->save();
+
+            $this->messageManager->addSuccess(__('The newsletter template has been saved.'));
+            $this->_getSession()->setFormData(false);
+
+            $this->_redirect('*/template');
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError(nl2br($e->getMessage()));
+            $this->_getSession()->setData('newsletter_template_form_data', $this->getRequest()->getParams());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('An error occurred while saving this template.'));
+            $this->_getSession()->setData('newsletter_template_form_data', $this->getRequest()->getParams());
+        }
+
+        $this->_forward('new');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Manage.php b/app/code/Magento/Newsletter/Controller/Manage.php
index 757c23c0be5f9dcff7ae2493a95254b8ed1bb916..15e28665c013d2d0b5218a126741d8c17e7bc54b 100644
--- a/app/code/Magento/Newsletter/Controller/Manage.php
+++ b/app/code/Magento/Newsletter/Controller/Manage.php
@@ -110,58 +110,4 @@ class Manage extends \Magento\Framework\App\Action\Action
         }
         return parent::dispatch($request);
     }
-
-    /**
-     * Managing newsletter subscription page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        if ($block = $this->_view->getLayout()->getBlock('customer_newsletter')) {
-            $block->setRefererUrl($this->_redirect->getRefererUrl());
-        }
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Newsletter Subscription'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save newsletter subscription preference action
-     *
-     * @return void|null
-     */
-    public function saveAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('customer/account/');
-        }
-
-        $customerId = $this->_customerSession->getCustomerId();
-        if (is_null($customerId)) {
-            $this->messageManager->addError(__('Something went wrong while saving your subscription.'));
-        } else {
-            try {
-                $customer = $this->_customerAccountService->getCustomer($customerId);
-                $storeId = $this->_storeManager->getStore()->getId();
-                $customerDetails = $this->_customerDetailsBuilder->setAddresses(null)
-                    ->setCustomer($this->_customerBuilder->populate($customer)->setStoreId($storeId)->create())
-                    ->create();
-                $this->_customerAccountService->updateCustomer($customerDetails);
-
-                if ((boolean)$this->getRequest()->getParam('is_subscribed', false)) {
-                    $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
-                    $this->messageManager->addSuccess(__('We saved the subscription.'));
-                } else {
-                    $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
-                    $this->messageManager->addSuccess(__('We removed the subscription.'));
-                }
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Something went wrong while saving your subscription.'));
-            }
-        }
-        $this->_redirect('customer/account/');
-    }
 }
diff --git a/app/code/Magento/Newsletter/Controller/Manage/Index.php b/app/code/Magento/Newsletter/Controller/Manage/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d0b45d07492d3282fe0216c3f090531fd60fd2e
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Manage/Index.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Manage;
+
+class Index extends \Magento\Newsletter\Controller\Manage
+{
+    /**
+     * Managing newsletter subscription page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        if ($block = $this->_view->getLayout()->getBlock('customer_newsletter')) {
+            $block->setRefererUrl($this->_redirect->getRefererUrl());
+        }
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('Newsletter Subscription'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Manage/Save.php b/app/code/Magento/Newsletter/Controller/Manage/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..04eac75883c72db1b04055c847a7049c25057e7e
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Manage/Save.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Manage;
+
+class Save extends \Magento\Newsletter\Controller\Manage
+{
+    /**
+     * Save newsletter subscription preference action
+     *
+     * @return void|null
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            return $this->_redirect('customer/account/');
+        }
+
+        $customerId = $this->_customerSession->getCustomerId();
+        if (is_null($customerId)) {
+            $this->messageManager->addError(__('Something went wrong while saving your subscription.'));
+        } else {
+            try {
+                $customer = $this->_customerAccountService->getCustomer($customerId);
+                $storeId = $this->_storeManager->getStore()->getId();
+                $customerDetails = $this->_customerDetailsBuilder->setAddresses(null)
+                    ->setCustomer($this->_customerBuilder->populate($customer)->setStoreId($storeId)->create())
+                    ->create();
+                $this->_customerAccountService->updateCustomer($customerDetails);
+
+                if ((boolean)$this->getRequest()->getParam('is_subscribed', false)) {
+                    $this->_subscriberFactory->create()->subscribeCustomerById($customerId);
+                    $this->messageManager->addSuccess(__('We saved the subscription.'));
+                } else {
+                    $this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);
+                    $this->messageManager->addSuccess(__('We removed the subscription.'));
+                }
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong while saving your subscription.'));
+            }
+        }
+        $this->_redirect('customer/account/');
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Subscriber.php b/app/code/Magento/Newsletter/Controller/Subscriber.php
index aa593062955f1789d39e31bc65497eef236e4121..e8f68a670c97444a1315297e15223b18367a2887 100644
--- a/app/code/Magento/Newsletter/Controller/Subscriber.php
+++ b/app/code/Magento/Newsletter/Controller/Subscriber.php
@@ -90,143 +90,4 @@ class Subscriber extends \Magento\Framework\App\Action\Action
         $this->_customerSession = $customerSession;
         $this->_customerHelper = $customerHelper;
     }
-
-    /**
-     * New subscription action
-     *
-     * @throws \Magento\Framework\Model\Exception
-     * @return void
-     */
-    public function newAction()
-    {
-        if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
-            $email = (string)$this->getRequest()->getPost('email');
-
-            try {
-                $this->validateEmailFormat($email);
-                $this->validateGuestSubscription();
-                $this->validateEmailAvailable($email);
-
-                $status = $this->_subscriberFactory->create()->subscribe($email);
-                if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
-                    $this->messageManager->addSuccess(__('The confirmation request has been sent.'));
-                } else {
-                    $this->messageManager->addSuccess(__('Thank you for your subscription.'));
-                }
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('There was a problem with the subscription: %1', $e->getMessage())
-                );
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong with the subscription.'));
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Subscription confirm action
-     * @return void
-     */
-    public function confirmAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        $code = (string)$this->getRequest()->getParam('code');
-
-        if ($id && $code) {
-            /** @var \Magento\Newsletter\Model\Subscriber $subscriber */
-            $subscriber = $this->_subscriberFactory->create()->load($id);
-
-            if ($subscriber->getId() && $subscriber->getCode()) {
-                if ($subscriber->confirm($code)) {
-                    $this->messageManager->addSuccess(__('Your subscription has been confirmed.'));
-                } else {
-                    $this->messageManager->addError(__('This is an invalid subscription confirmation code.'));
-                }
-            } else {
-                $this->messageManager->addError(__('This is an invalid subscription ID.'));
-            }
-        }
-
-        $this->getResponse()->setRedirect($this->_storeManager->getStore()->getBaseUrl());
-    }
-
-    /**
-     * Unsubscribe newsletter
-     * @return void
-     */
-    public function unsubscribeAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        $code = (string)$this->getRequest()->getParam('code');
-
-        if ($id && $code) {
-            try {
-                $this->_subscriberFactory->create()->load($id)->setCheckCode($code)->unsubscribe();
-                $this->messageManager->addSuccess(__('You have been unsubscribed.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addException($e, $e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong with the un-subscription.'));
-            }
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Validates that the email address isn't being used by a different account.
-     *
-     * @param string $email
-     * @throws \Magento\Framework\Model\Exception
-     * @return void
-     */
-    protected function validateEmailAvailable($email)
-    {
-        $websiteId = $this->_storeManager->getStore()->getWebsiteId();
-        if ($this->_customerSession->getCustomerDataObject()->getEmail() !== $email
-            && !$this->_customerService->isEmailAvailable($email, $websiteId)
-        ) {
-            throw new \Magento\Framework\Model\Exception(__('This email address is already assigned to another user.'));
-        }
-    }
-
-    /**
-     * Validates that if the current user is a guest, that they can subscribe to a newsletter.
-     *
-     * @throws \Magento\Framework\Model\Exception
-     * @return void
-     */
-    protected function validateGuestSubscription()
-    {
-        if ($this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface')
-                ->getValue(
-                    \Magento\Newsletter\Model\Subscriber::XML_PATH_ALLOW_GUEST_SUBSCRIBE_FLAG,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                ) != 1
-            && !$this->_customerSession->isLoggedIn()
-        ) {
-            throw new \Magento\Framework\Model\Exception(
-                __(
-                    'Sorry, but the administrator denied subscription for guests. '
-                    . 'Please <a href="%1">register</a>.',
-                    $this->_customerHelper->getRegisterUrl()
-                )
-            );
-        }
-    }
-
-    /**
-     * Validates the format of the email address
-     *
-     * @param string $email
-     * @throws \Magento\Framework\Model\Exception
-     * @return void
-     */
-    protected function validateEmailFormat($email)
-    {
-        if (!\Zend_Validate::is($email, 'EmailAddress')) {
-            throw new \Magento\Framework\Model\Exception(__('Please enter a valid email address.'));
-        }
-    }
 }
diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php
new file mode 100644
index 0000000000000000000000000000000000000000..9de63dae42db4a7fb6d6b44412f303ebefcaf36e
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Subscriber/Confirm.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Subscriber;
+
+class Confirm extends \Magento\Newsletter\Controller\Subscriber
+{
+    /**
+     * Subscription confirm action
+     * @return void
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        $code = (string)$this->getRequest()->getParam('code');
+
+        if ($id && $code) {
+            /** @var \Magento\Newsletter\Model\Subscriber $subscriber */
+            $subscriber = $this->_subscriberFactory->create()->load($id);
+
+            if ($subscriber->getId() && $subscriber->getCode()) {
+                if ($subscriber->confirm($code)) {
+                    $this->messageManager->addSuccess(__('Your subscription has been confirmed.'));
+                } else {
+                    $this->messageManager->addError(__('This is an invalid subscription confirmation code.'));
+                }
+            } else {
+                $this->messageManager->addError(__('This is an invalid subscription ID.'));
+            }
+        }
+
+        $this->getResponse()->setRedirect($this->_storeManager->getStore()->getBaseUrl());
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c854b01609c2e49ce50c272c44091f0a00ed98c
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Subscriber/NewAction.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Subscriber;
+
+class NewAction extends \Magento\Newsletter\Controller\Subscriber
+{
+    /**
+     * Validates that the email address isn't being used by a different account.
+     *
+     * @param string $email
+     * @throws \Magento\Framework\Model\Exception
+     * @return void
+     */
+    protected function validateEmailAvailable($email)
+    {
+        $websiteId = $this->_storeManager->getStore()->getWebsiteId();
+        if ($this->_customerSession->getCustomerDataObject()->getEmail() !== $email
+            && !$this->_customerService->isEmailAvailable($email, $websiteId)
+        ) {
+            throw new \Magento\Framework\Model\Exception(__('This email address is already assigned to another user.'));
+        }
+    }
+
+    /**
+     * Validates that if the current user is a guest, that they can subscribe to a newsletter.
+     *
+     * @throws \Magento\Framework\Model\Exception
+     * @return void
+     */
+    protected function validateGuestSubscription()
+    {
+        if ($this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface')
+                ->getValue(
+                    \Magento\Newsletter\Model\Subscriber::XML_PATH_ALLOW_GUEST_SUBSCRIBE_FLAG,
+                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                ) != 1
+            && !$this->_customerSession->isLoggedIn()
+        ) {
+            throw new \Magento\Framework\Model\Exception(
+                __(
+                    'Sorry, but the administrator denied subscription for guests. '
+                    . 'Please <a href="%1">register</a>.',
+                    $this->_customerHelper->getRegisterUrl()
+                )
+            );
+        }
+    }
+
+    /**
+     * Validates the format of the email address
+     *
+     * @param string $email
+     * @throws \Magento\Framework\Model\Exception
+     * @return void
+     */
+    protected function validateEmailFormat($email)
+    {
+        if (!\Zend_Validate::is($email, 'EmailAddress')) {
+            throw new \Magento\Framework\Model\Exception(__('Please enter a valid email address.'));
+        }
+    }
+
+    /**
+     * New subscription action
+     *
+     * @throws \Magento\Framework\Model\Exception
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
+            $email = (string)$this->getRequest()->getPost('email');
+
+            try {
+                $this->validateEmailFormat($email);
+                $this->validateGuestSubscription();
+                $this->validateEmailAvailable($email);
+
+                $status = $this->_subscriberFactory->create()->subscribe($email);
+                if ($status == \Magento\Newsletter\Model\Subscriber::STATUS_NOT_ACTIVE) {
+                    $this->messageManager->addSuccess(__('The confirmation request has been sent.'));
+                } else {
+                    $this->messageManager->addSuccess(__('Thank you for your subscription.'));
+                }
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('There was a problem with the subscription: %1', $e->getMessage())
+                );
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong with the subscription.'));
+            }
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Newsletter/Controller/Subscriber/Unsubscribe.php b/app/code/Magento/Newsletter/Controller/Subscriber/Unsubscribe.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6ccb21fcabc6281cd15c9d24287cffb3b3f58b0
--- /dev/null
+++ b/app/code/Magento/Newsletter/Controller/Subscriber/Unsubscribe.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Newsletter\Controller\Subscriber;
+
+class Unsubscribe extends \Magento\Newsletter\Controller\Subscriber
+{
+    /**
+     * Unsubscribe newsletter
+     * @return void
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        $code = (string)$this->getRequest()->getParam('code');
+
+        if ($id && $code) {
+            try {
+                $this->_subscriberFactory->create()->load($id)->setCheckCode($code)->unsubscribe();
+                $this->messageManager->addSuccess(__('You have been unsubscribed.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addException($e, $e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong with the un-subscription.'));
+            }
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config.php b/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php
similarity index 90%
rename from app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config.php
rename to app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php
index 1e00e6d40329190d8555fae67d144e760a813f7d..4ff66cddf0d42c36c44d17c11f298be585e4fba4 100644
--- a/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config.php
+++ b/app/code/Magento/OfflineShipping/Controller/Adminhtml/System/Config/ExportTablerates.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,15 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\OfflineShipping\Controller\Adminhtml\System;
+namespace Magento\OfflineShipping\Controller\Adminhtml\System\Config;
 
-use Magento\Framework\App\ResponseInterface;
-use Magento\Backend\Controller\Adminhtml\System\AbstractConfig;
+use \Magento\Framework\App\ResponseInterface;
 
-/**
- * System Configuration controller
- */
-class Config extends AbstractConfig
+class ExportTablerates extends \Magento\Backend\Controller\Adminhtml\System\AbstractConfig
 {
     /**
      * @var \Magento\Framework\App\Response\Http\FileFactory
@@ -63,7 +60,7 @@ class Config extends AbstractConfig
      *
      * @return ResponseInterface
      */
-    public function exportTableratesAction()
+    public function execute()
     {
         $fileName = 'tablerates.csv';
         /** @var $gridBlock \Magento\OfflineShipping\Block\Adminhtml\Carrier\Tablerate\Grid */
diff --git a/app/code/Magento/Ogone/Controller/Api.php b/app/code/Magento/Ogone/Controller/Api.php
index f19f2c69938aab7973bf5cc908ccd53a5fe8cab6..61ab2da4e166aa7ba73ddd4d06be4ff1f24db2c1 100644
--- a/app/code/Magento/Ogone/Controller/Api.php
+++ b/app/code/Magento/Ogone/Controller/Api.php
@@ -135,77 +135,6 @@ class Api extends \Magento\Framework\App\Action\Action
         return true;
     }
 
-    /**
-     * Load place from layout to make POST on Ogone
-     *
-     * @return void
-     */
-    public function placeformAction()
-    {
-        $lastIncrementId = $this->_getCheckout()->getLastRealOrderId();
-        if ($lastIncrementId) {
-            $order = $this->_salesOrderFactory->create()->loadByIncrementId($lastIncrementId);
-            if ($order->getId()) {
-                $order->setState(
-                    \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT,
-                    \Magento\Ogone\Model\Api::PENDING_OGONE_STATUS,
-                    __('Start Ogone Processing')
-                );
-                $order->save();
-
-                $this->_getApi()->debugOrder($order);
-            }
-        }
-
-        $this->_getCheckout()->getQuote()->setIsActive(false)->save();
-        $this->_getCheckout()->setOgoneQuoteId($this->_getCheckout()->getQuoteId());
-        $this->_getCheckout()->setOgoneLastSuccessQuoteId($this->_getCheckout()->getLastSuccessQuoteId());
-        $this->_getCheckout()->clearQuote();
-
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Display our pay page, need to Ogone payment with external pay page mode
-     *
-     * @return void
-     */
-    public function paypageAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Action to control postback data from Ogone
-     *
-     * @return null|false
-     */
-    public function postBackAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->getResponse()->setHeader("Status", "404 Not Found");
-            return false;
-        }
-
-        $this->_ogoneProcess();
-    }
-
-    /**
-     * Action to process Ogone offline data
-     *
-     * @return null|false
-     */
-    public function offlineProcessAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->getResponse()->setHeader("Status", "404 Not Found");
-            return false;
-        }
-        $this->_ogoneProcess();
-    }
-
     /**
      * Made offline Ogone data processing, depending of incoming statuses
      *
@@ -236,22 +165,6 @@ class Api extends \Magento\Framework\App\Action\Action
         }
     }
 
-    /**
-     * When payment gateway accept the payment, it will land to here
-     * need to change order status as processed Ogone
-     * update transaction id
-     *
-     * @return void
-     */
-    public function acceptAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $this->_ogoneProcess();
-    }
-
     /**
      * Process success action by accept url
      *
@@ -402,23 +315,6 @@ class Api extends \Magento\Framework\App\Action\Action
         return $this;
     }
 
-    /**
-     * The payment result is uncertain
-     * exception status can be 52 or 92
-     * need to change order status as processing Ogone
-     * update transaction id
-     *
-     * @return void
-     */
-    public function exceptionAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $this->_exceptionProcess();
-    }
-
     /**
      * Process exception action by Ogone exception url
      *
@@ -475,23 +371,6 @@ class Api extends \Magento\Framework\App\Action\Action
         $this->_redirect('checkout/onepage/success');
     }
 
-    /**
-     * When payment got decline
-     * need to change order status to cancelled
-     * take the user back to shopping cart
-     *
-     * @return void
-     */
-    public function declineAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $this->_getCheckout()->setQuoteId($this->_getCheckout()->getOgoneQuoteId());
-        $this->_declineProcess();
-    }
-
     /**
      * Process decline action by Ogone decline url
      *
@@ -505,36 +384,6 @@ class Api extends \Magento\Framework\App\Action\Action
         $this->_cancelOrder($status, $comment);
     }
 
-    /**
-     * When user cancel the payment
-     * change order status to cancelled
-     * need to redirect user to shopping cart
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        if (!$this->_validateOgoneData()) {
-            $this->_redirect('checkout/cart');
-            return;
-        }
-        $this->_getCheckout()->setQuoteId($this->_getCheckout()->getOgoneQuoteId());
-        $this->_cancelProcess();
-    }
-
-    /**
-     * Process cancel action by cancel url
-     *
-     * @return $this
-     */
-    public function _cancelProcess()
-    {
-        $status = \Magento\Ogone\Model\Api::CANCEL_OGONE_STATUS;
-        $comment = __('The order was canceled on the Ogone side.');
-        $this->_cancelOrder($status, $comment);
-        return $this;
-    }
-
     /**
      * Cancel action, used for decline and cancel processes
      *
diff --git a/app/code/Magento/Ogone/Controller/Api/Accept.php b/app/code/Magento/Ogone/Controller/Api/Accept.php
new file mode 100644
index 0000000000000000000000000000000000000000..77af08b98c11a0bc63c128c428e323163c717aec
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Accept.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class Accept extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * When payment gateway accept the payment, it will land to here
+     * need to change order status as processed Ogone
+     * update transaction id
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateOgoneData()) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $this->_ogoneProcess();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/Cancel.php b/app/code/Magento/Ogone/Controller/Api/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..78e8024c91ca3802031de08181af75506882f72a
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Cancel.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class Cancel extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * Process cancel action by cancel url
+     *
+     * @return $this
+     */
+    public function _cancelProcess()
+    {
+        $status = \Magento\Ogone\Model\Api::CANCEL_OGONE_STATUS;
+        $comment = __('The order was canceled on the Ogone side.');
+        $this->_cancelOrder($status, $comment);
+        return $this;
+    }
+
+    /**
+     * When user cancel the payment
+     * change order status to cancelled
+     * need to redirect user to shopping cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateOgoneData()) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $this->_getCheckout()->setQuoteId($this->_getCheckout()->getOgoneQuoteId());
+        $this->_cancelProcess();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/Decline.php b/app/code/Magento/Ogone/Controller/Api/Decline.php
new file mode 100644
index 0000000000000000000000000000000000000000..550c4eb182b99b1ee4b5cc31c1e4b9c31bcc8e7b
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Decline.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class Decline extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * When payment got decline
+     * need to change order status to cancelled
+     * take the user back to shopping cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateOgoneData()) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $this->_getCheckout()->setQuoteId($this->_getCheckout()->getOgoneQuoteId());
+        $this->_declineProcess();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/Exception.php b/app/code/Magento/Ogone/Controller/Api/Exception.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6808153ccde085ad12721b3b7746663df21b006
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Exception.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class Exception extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * The payment result is uncertain
+     * exception status can be 52 or 92
+     * need to change order status as processing Ogone
+     * update transaction id
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_validateOgoneData()) {
+            $this->_redirect('checkout/cart');
+            return;
+        }
+        $this->_exceptionProcess();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/OfflineProcess.php b/app/code/Magento/Ogone/Controller/Api/OfflineProcess.php
new file mode 100644
index 0000000000000000000000000000000000000000..4e709f1d3fc339de5471d9935be3066f3bcf1e57
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/OfflineProcess.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Action to process Ogone offline data
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class OfflineProcess extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if (!$this->_validateOgoneData()) {
+            $this->getResponse()->setHeader("Status", "404 Not Found");
+            return false;
+        }
+        $this->_ogoneProcess();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/Paypage.php b/app/code/Magento/Ogone/Controller/Api/Paypage.php
new file mode 100644
index 0000000000000000000000000000000000000000..200f5d8ea13f341aba721701451ab35372a933e4
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Paypage.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class Paypage extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * Display our pay page, need to Ogone payment with external pay page mode
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/Placeform.php b/app/code/Magento/Ogone/Controller/Api/Placeform.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bb48353e9a36a4f63355eff51df0d66c0afe5a4
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/Placeform.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+use \Magento\Sales\Model\Order;
+
+class Placeform extends \Magento\Ogone\Controller\Api
+{
+    /**
+     * Load place from layout to make POST on Ogone
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $lastIncrementId = $this->_getCheckout()->getLastRealOrderId();
+        if ($lastIncrementId) {
+            $order = $this->_salesOrderFactory->create()->loadByIncrementId($lastIncrementId);
+            if ($order->getId()) {
+                $order->setState(
+                    \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT,
+                    \Magento\Ogone\Model\Api::PENDING_OGONE_STATUS,
+                    __('Start Ogone Processing')
+                );
+                $order->save();
+
+                $this->_getApi()->debugOrder($order);
+            }
+        }
+
+        $this->_getCheckout()->getQuote()->setIsActive(false)->save();
+        $this->_getCheckout()->setOgoneQuoteId($this->_getCheckout()->getQuoteId());
+        $this->_getCheckout()->setOgoneLastSuccessQuoteId($this->_getCheckout()->getLastSuccessQuoteId());
+        $this->_getCheckout()->clearQuote();
+
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Ogone/Controller/Api/PostBack.php b/app/code/Magento/Ogone/Controller/Api/PostBack.php
new file mode 100644
index 0000000000000000000000000000000000000000..7eb398bf6ec1c882833144dcf665011233781945
--- /dev/null
+++ b/app/code/Magento/Ogone/Controller/Api/PostBack.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Action to control postback data from Ogone
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Ogone\Controller\Api;
+
+class PostBack extends OfflineProcess
+{
+}
diff --git a/app/code/Magento/PageCache/Controller/Adminhtml/PageCache.php b/app/code/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfig.php
similarity index 91%
rename from app/code/Magento/PageCache/Controller/Adminhtml/PageCache.php
rename to app/code/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfig.php
index 92c3abc34b6c4c1bad465e977dbc9a1a26ce873a..5816ddbd41d59fd80bb78d8ba41c52f852a8b7cb 100644
--- a/app/code/Magento/PageCache/Controller/Adminhtml/PageCache.php
+++ b/app/code/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfig.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,12 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\PageCache\Controller\Adminhtml;
+namespace Magento\PageCache\Controller\Adminhtml\PageCache;
 
-/**
- * Page cache admin controller
- */
-class PageCache extends \Magento\Backend\App\Action
+class ExportVarnishConfig extends \Magento\Backend\App\Action
 {
     /**
      * @var \Magento\Backend\App\Response\Http\FileFactory
@@ -58,7 +56,7 @@ class PageCache extends \Magento\Backend\App\Action
      *
      * @return \Magento\Framework\App\ResponseInterface
      */
-    public function exportVarnishConfigAction()
+    public function execute()
     {
         $fileName = 'varnish.vcl';
         $content = $this->config->getVclFile();
diff --git a/app/code/Magento/PageCache/Controller/Block.php b/app/code/Magento/PageCache/Controller/Block.php
index f4e3cc9a1a652f303fa006259f5743449dee3678..572babf097c6213ce8fc376baa0ce18c5ac29b2a 100644
--- a/app/code/Magento/PageCache/Controller/Block.php
+++ b/app/code/Magento/PageCache/Controller/Block.php
@@ -27,52 +27,6 @@ namespace Magento\PageCache\Controller;
 
 class Block extends \Magento\Framework\App\Action\Action
 {
-    /**
-     * Returns block content depends on ajax request
-     *
-     * @return void
-     */
-    public function renderAction()
-    {
-        if (!$this->getRequest()->isAjax()) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        $blocks = $this->_getBlocks();
-        $data = array();
-        foreach ($blocks as $blockName => $blockInstance) {
-            $data[$blockName] = $blockInstance->toHtml();
-        }
-
-        $this->getResponse()->setPrivateHeaders(\Magento\PageCache\Helper\Data::PRIVATE_MAX_AGE_CACHE);
-        $this->getResponse()->appendBody(json_encode($data));
-    }
-
-    /**
-     * Returns block content as part of ESI request from Varnish
-     *
-     * @return void
-     */
-    public function esiAction()
-    {
-        $response = $this->getResponse();
-        $blocks = $this->_getBlocks();
-        $html = '';
-        $ttl = 0;
-
-        if (!empty($blocks)) {
-            $blockInstance = array_shift($blocks);
-            $html = $blockInstance->toHtml();
-            $ttl = $blockInstance->getTtl();
-            if ($blockInstance instanceof \Magento\Framework\View\Block\IdentityInterface) {
-                $response->setHeader('X-Magento-Tags', implode(',', $blockInstance->getIdentities()));
-            }
-        }
-        $response->appendBody($html);
-        $response->setPublicHeaders($ttl);
-    }
-
     /**
      * Get blocks from layout by handles
      *
diff --git a/app/code/Magento/PageCache/Controller/Block/Esi.php b/app/code/Magento/PageCache/Controller/Block/Esi.php
new file mode 100644
index 0000000000000000000000000000000000000000..109fb3ae74c799aa67a226eb3f1a62a3a0e2213f
--- /dev/null
+++ b/app/code/Magento/PageCache/Controller/Block/Esi.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\PageCache\Controller\Block;
+
+class Esi extends \Magento\PageCache\Controller\Block
+{
+    /**
+     * Returns block content as part of ESI request from Varnish
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = $this->getResponse();
+        $blocks = $this->_getBlocks();
+        $html = '';
+        $ttl = 0;
+
+        if (!empty($blocks)) {
+            $blockInstance = array_shift($blocks);
+            $html = $blockInstance->toHtml();
+            $ttl = $blockInstance->getTtl();
+            if ($blockInstance instanceof \Magento\Framework\View\Block\IdentityInterface) {
+                $response->setHeader('X-Magento-Tags', implode(',', $blockInstance->getIdentities()));
+            }
+        }
+        $response->appendBody($html);
+        $response->setPublicHeaders($ttl);
+    }
+}
diff --git a/app/code/Magento/PageCache/Controller/Block/Render.php b/app/code/Magento/PageCache/Controller/Block/Render.php
new file mode 100644
index 0000000000000000000000000000000000000000..27cdf6f470c6aaf5bc06a7b6ff6e289dac4192bd
--- /dev/null
+++ b/app/code/Magento/PageCache/Controller/Block/Render.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\PageCache\Controller\Block;
+
+class Render extends \Magento\PageCache\Controller\Block
+{
+    /**
+     * Returns block content depends on ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->getRequest()->isAjax()) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $blocks = $this->_getBlocks();
+        $data = array();
+        foreach ($blocks as $blockName => $blockInstance) {
+            $data[$blockName] = $blockInstance->toHtml();
+        }
+
+        $this->getResponse()->setPrivateHeaders(\Magento\PageCache\Helper\Data::PRIVATE_MAX_AGE_CACHE);
+        $this->getResponse()->appendBody(json_encode($data));
+    }
+}
diff --git a/app/code/Magento/PageCache/Model/Observer.php b/app/code/Magento/PageCache/Model/Observer.php
index 6482be561c8c8abf43840799cf96a8ab2698458c..eade45976adc82dfe98d1c7963e254f291af399b 100644
--- a/app/code/Magento/PageCache/Model/Observer.php
+++ b/app/code/Magento/PageCache/Model/Observer.php
@@ -55,6 +55,11 @@ class Observer
      */
     protected $_session;
 
+    /**
+     * @var \Magento\Framework\Escaper
+     */
+    protected $_escaper;
+    
     /**
      * @var \Magento\Framework\App\PageCache\FormKey
      */
@@ -69,6 +74,7 @@ class Observer
      * @param \Magento\Framework\App\Cache\TypeListInterface $typeList
      * @param \Magento\Framework\Session\Generic $session
      * @param \Magento\Framework\App\PageCache\FormKey $formKey
+     * @param \Magento\Framework\Escaper $escaper
      */
     public function __construct(
         \Magento\PageCache\Model\Config $config,
@@ -76,7 +82,8 @@ class Observer
         \Magento\PageCache\Helper\Data $helper,
         \Magento\Framework\App\Cache\TypeListInterface $typeList,
         \Magento\Framework\App\PageCache\FormKey $formKey,
-        \Magento\Framework\Session\Generic $session
+        \Magento\Framework\Session\Generic $session,
+        \Magento\Framework\Escaper $escaper
     ) {
         $this->_config = $config;
         $this->_cache = $cache;
@@ -84,6 +91,7 @@ class Observer
         $this->_typeList = $typeList;
         $this->_session = $session;
         $this->_formKey = $formKey;
+        $this->_escaper = $escaper;
     }
 
     /**
@@ -164,6 +172,8 @@ class Observer
      *
      * @param \Magento\Framework\Event\Observer $observer
      * @return void
+     * 
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function flushAllCache(\Magento\Framework\Event\Observer $observer)
     {
@@ -190,12 +200,17 @@ class Observer
      *
      * @param \Magento\Framework\Event\Observer $observer
      * @return void
+     * 
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function registerFormKeyFromCookie(\Magento\Framework\Event\Observer $observer)
     {
         $formKeyFromCookie = $this->_formKey->get();
         if ($formKeyFromCookie) {
-            $this->_session->setData(\Magento\Framework\Data\Form\FormKey::FORM_KEY, $formKeyFromCookie);
+            $this->_session->setData(
+                \Magento\Framework\Data\Form\FormKey::FORM_KEY,
+                $this->_escaper->escapeHtml($formKeyFromCookie)
+            );
         }
     }
 }
diff --git a/app/code/Magento/PageCache/etc/events.xml b/app/code/Magento/PageCache/etc/events.xml
index b99208180d601abc154ab1a718559a4dea42d3d4..a00c8488bf151f2c7124fdd9cbcbad223f52e075 100644
--- a/app/code/Magento/PageCache/etc/events.xml
+++ b/app/code/Magento/PageCache/etc/events.xml
@@ -57,7 +57,7 @@
     <event name="controller_action_postdispatch_adminhtml_system_currency_saveRates">
         <observer name="flush_all_pagecache" instance="Magento\PageCache\Model\Observer" method="invalidateCache" />
     </event>
-    <event name="controller_action_postdispatch_adminhtml_system_config_save_index">
+    <event name="controller_action_postdispatch_adminhtml_system_config_save">
         <observer name="flush_all_pagecache" instance="Magento\PageCache\Model\Observer" method="invalidateCache" />
     </event>
     <event name="controller_action_postdispatch_catalog_product_save">
diff --git a/app/code/Magento/PageCache/view/frontend/web/js/comments.js b/app/code/Magento/PageCache/view/frontend/web/js/comments.js
index 957d391f620799bc12dbde6ccd59d2f46a940da2..72341b5fcc51c67b3766b0f374e869c86854736e 100644
--- a/app/code/Magento/PageCache/view/frontend/web/js/comments.js
+++ b/app/code/Magento/PageCache/view/frontend/web/js/comments.js
@@ -23,11 +23,18 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 /*jshint browser:true jquery:true expr:true*/
-(function ($) {
+(function ($, win) {
     "use strict";
     $.fn.comments = function () {
         var elements = [];
         var lookup = function (el) {
+            if (el.is('iframe')) {
+                var hostName = win.location.hostname,
+                    iFrameHostName = $('<a>').prop('href', el.prop('src')).prop('hostname');
+                if (hostName != iFrameHostName) {
+                    return elements;
+                }
+            }
             el.contents().each(function (i, el) {
                 if (el.nodeType == 8) {
                     elements.push(el);
@@ -39,4 +46,4 @@
         lookup(this);
         return elements;
     };
-})(jQuery);
\ No newline at end of file
+})(jQuery, window);
\ No newline at end of file
diff --git a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
index 3dc403f9500132eb97d012d2121fd4925a343a7a..d678846945b9413d6991210a8d6aaccaf98c9f3a 100644
--- a/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
+++ b/app/code/Magento/PageCache/view/frontend/web/js/page-cache.js
@@ -46,6 +46,9 @@
         _searchPlaceholders: function (elements) {
             var placeholders = [],
                 tmp = {};
+            if (!elements.length) {
+                return placeholders;
+            }
             for (var i = 0; i < elements.length; i++) {
                 var el = elements[i],
                     matches = this.options.patternPlaceholderOpen.exec(el.nodeValue),
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement.php b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement.php
index 50d80e8e1cf5b88ccff7d1a175161d184e571332..89568601b539551f9fb9c25e6cc54fce5720f325 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement.php
@@ -39,6 +39,6 @@ class Agreement extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Paypal';
         $this->_headerText = __('Billing Agreements');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/View.php b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/View.php
index dfd2eb705ec01edcb4b7a9abf625de4275854125..c26fb4c039de1377cf6f3609c1e4543fd1d17436 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/View.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/Billing/Agreement/View.php
@@ -36,12 +36,12 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -64,13 +64,13 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         parent::_construct();
 
         if (!$this->_isAllowed('Magento_Paypal::actions_manage')) {
-            $this->_removeButton('delete');
+            $this->buttonList->remove('delete');
         }
-        $this->_removeButton('reset');
-        $this->_removeButton('save');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('save');
         $this->setId('billing_agreement_view');
 
-        $this->_addButton(
+        $this->buttonList->add(
             'back',
             array(
                 'label' => __('Back'),
@@ -83,7 +83,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         $agreement = $this->_getBillingAgreement();
         if ($agreement && $agreement->canCancel() && $this->_isAllowed('Magento_Paypal::actions_manage')) {
             $confirmText = __('Are you sure you want to do this?');
-            $this->_addButton(
+            $this->buttonList->add(
                 'cancel',
                 array(
                     'label' => __('Cancel'),
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Details.php b/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Details.php
index 367595927c94ef9072f5378d6ae9f8409ae97ffa..6eb71e4da6342747bcd985a2fdcbcf2c1b675451 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Details.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Details.php
@@ -41,7 +41,9 @@ class Details extends \Magento\Backend\Block\Widget\Form\Container
         parent::_construct();
         $this->_controller = '';
         $this->_headerText = __('View Transaction Details');
-        $this->_removeButton('reset')->_removeButton('delete')->_removeButton('save');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
+        $this->buttonList->remove('save');
     }
 
     /**
diff --git a/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Report.php b/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Report.php
index 85b8c8816076c7e6d18e5e95c6524cf346fe2400..2a6fc672083d994b21908c809e03f183ef8f04dd 100644
--- a/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Report.php
+++ b/app/code/Magento/Paypal/Block/Adminhtml/Settlement/Report.php
@@ -41,12 +41,12 @@ class Report extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_settlement_report';
         $this->_headerText = __('PayPal Settlement Reports');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $message = __(
             'We are connecting to the PayPal SFTP server to retrieve new reports. Are you sure you want to continue?'
         );
         if (true == $this->_authorization->isAllowed('Magento_Paypal::fetch')) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'fetch',
                 array(
                     'label' => __('Fetch Updates'),
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement.php
index b79b75cbc8c7ce6537f2165476a868924a59696b..61198705303d8903829a099235a18aeffaecaf37 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement.php
@@ -45,130 +45,6 @@ class Agreement extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Billing agreements
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Billing Agreements'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Paypal::paypal_billing_agreement');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Ajax action for billing agreements
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * View billing agreement action
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $agreementModel = $this->_initBillingAgreement();
-
-        if ($agreementModel) {
-            $this->_title->add(__('Billing Agreements'));
-            $this->_title->add(sprintf("#%s", $agreementModel->getReferenceId()));
-
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Paypal::paypal_billing_agreement');
-            $this->_view->renderLayout();
-            return;
-        }
-
-        $this->_redirect('paypal/*/');
-        return;
-    }
-
-    /**
-     * Related orders ajax action
-     *
-     * @return void
-     */
-    public function ordersGridAction()
-    {
-        $this->_initBillingAgreement();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Customer billing agreements ajax action
-     *
-     * @return void
-     */
-    public function customerGridAction()
-    {
-        $this->_initCustomer();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Cancel billing agreement action
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $agreementModel = $this->_initBillingAgreement();
-
-        if ($agreementModel && $agreementModel->canCancel()) {
-            try {
-                $agreementModel->cancel();
-                $this->messageManager->addSuccess(__('You canceled the billing agreement.'));
-                $this->_redirect('paypal/*/view', array('_current' => true));
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('We could not cancel the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-            $this->_redirect('paypal/*/view', array('_current' => true));
-        }
-        return $this->_redirect('paypal/*/');
-    }
-
-    /**
-     * Delete billing agreement action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $agreementModel = $this->_initBillingAgreement();
-
-        if ($agreementModel) {
-            try {
-                $agreementModel->delete();
-                $this->messageManager->addSuccess(__('You deleted the billing agreement.'));
-                $this->_redirect('paypal/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('We could not delete the billing agreement.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-            $this->_redirect('paypal/*/view', array('_current' => true));
-        }
-        $this->_redirect('paypal/*/');
-    }
-
     /**
      * Initialize billing agreement by ID specified in request
      *
@@ -188,20 +64,6 @@ class Agreement extends \Magento\Backend\App\Action
         return $agreementModel;
     }
 
-    /**
-     * Initialize customer by ID specified in request
-     *
-     * @return $this
-     */
-    protected function _initCustomer()
-    {
-        $customerId = (int)$this->getRequest()->getParam('id');
-        if ($customerId) {
-            $this->_coreRegistry->register('current_customer_id', $customerId);
-        }
-        return $this;
-    }
-
     /**
      * Check currently called action by permissions for current user
      *
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb3e2c997b8bef191179674cfa9cbc7ca3ce7f0f
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Cancel.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class Cancel extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * Cancel billing agreement action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $agreementModel = $this->_initBillingAgreement();
+
+        if ($agreementModel && $agreementModel->canCancel()) {
+            try {
+                $agreementModel->cancel();
+                $this->messageManager->addSuccess(__('You canceled the billing agreement.'));
+                $this->_redirect('paypal/*/view', array('_current' => true));
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('We could not cancel the billing agreement.'));
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+            $this->_redirect('paypal/*/view', array('_current' => true));
+        }
+        return $this->_redirect('paypal/*/');
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Catalog.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/CustomerGrid.php
similarity index 65%
rename from app/code/Magento/Rss/Controller/Adminhtml/Catalog.php
rename to app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/CustomerGrid.php
index c5a13a00ed8e2b32bb9a1b3a65800045010eb5e0..a5b1e3de3dc48ade3193c1421a451d8a19414971 100644
--- a/app/code/Magento/Rss/Controller/Adminhtml/Catalog.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/CustomerGrid.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,33 +22,32 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Adminhtml;
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
 
-/**
- * RSS Controller for Catalog feeds in Admin
- */
-class Catalog extends \Magento\Rss\Controller\Adminhtml\Authenticate
+class CustomerGrid extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
 {
     /**
-     * Notify stock action
+     * Initialize customer by ID specified in request
      *
-     * @return void
+     * @return $this
      */
-    public function notifystockAction()
+    protected function _initCustomer()
     {
-        $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
+        $customerId = (int)$this->getRequest()->getParam('id');
+        if ($customerId) {
+            $this->_coreRegistry->register('current_customer_id', $customerId);
+        }
+        return $this;
     }
 
     /**
-     * Review action
+     * Customer billing agreements ajax action
      *
      * @return void
      */
-    public function reviewAction()
+    public function execute()
     {
-        $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
+        $this->_initCustomer();
         $this->_view->loadLayout(false);
         $this->_view->renderLayout();
     }
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..906c9f0d75ca461fbccee498b3b0650ee17b3513
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Delete.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class Delete extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * Delete billing agreement action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $agreementModel = $this->_initBillingAgreement();
+
+        if ($agreementModel) {
+            try {
+                $agreementModel->delete();
+                $this->messageManager->addSuccess(__('You deleted the billing agreement.'));
+                $this->_redirect('paypal/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('We could not delete the billing agreement.'));
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+            $this->_redirect('paypal/*/view', array('_current' => true));
+        }
+        $this->_redirect('paypal/*/');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Grid.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..eaa856dceff0139ff4e456a01c3a926133c1eb44
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class Grid extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * Ajax action for billing agreements
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..106bec73d43c846c821b1c8feaeb2bfb372a4e7c
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class Index extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * Billing agreements
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Billing Agreements'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Paypal::paypal_billing_agreement');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/OrdersGrid.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/OrdersGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b65b93d7fcf22b33fcaec396c29631168a5364e
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/OrdersGrid.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class OrdersGrid extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * Related orders ajax action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initBillingAgreement();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/View.php b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..3fa35a263d576e6f6ae04511df844c15111c9d6d
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Billing/Agreement/View.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Billing\Agreement;
+
+class View extends \Magento\Paypal\Controller\Adminhtml\Billing\Agreement
+{
+    /**
+     * View billing agreement action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $agreementModel = $this->_initBillingAgreement();
+
+        if ($agreementModel) {
+            $this->_title->add(__('Billing Agreements'));
+            $this->_title->add(sprintf("#%s", $agreementModel->getReferenceId()));
+
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Paypal::paypal_billing_agreement');
+            $this->_view->renderLayout();
+            return;
+        }
+
+        $this->_redirect('paypal/*/');
+        return;
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
index 28c71a221eab36bb68f591856c92df660bb6f64d..5b285c4e0ee12a7b36dc5b87dae158ed01ad7a59 100644
--- a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports.php
@@ -71,96 +71,6 @@ class Reports extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Grid action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Ajax callback for grid actions
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * View transaction details action
-     *
-     * @return void
-     */
-    public function detailsAction()
-    {
-        $rowId = $this->getRequest()->getParam('id');
-        $row = $this->_rowFactory->create()->load($rowId);
-        if (!$row->getId()) {
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        $this->_coreRegistry->register('current_transaction', $row);
-        $this->_initAction();
-        $this->_title->add(__('View Transaction'));
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Paypal\Block\Adminhtml\Settlement\Details',
-                'settlementDetails'
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Forced fetch reports action
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function fetchAction()
-    {
-        try {
-            $reports = $this->_settlementFactory->create();
-            /* @var $reports \Magento\Paypal\Model\Report\Settlement */
-            $credentials = $reports->getSftpCredentials();
-            if (empty($credentials)) {
-                throw new \Magento\Framework\Model\Exception(__('We found nothing to fetch because of an empty configuration.'));
-            }
-            foreach ($credentials as $config) {
-                try {
-                    $fetched = $reports->fetchAndSave(
-                        \Magento\Paypal\Model\Report\Settlement::createConnection($config)
-                    );
-                    $this->messageManager->addSuccess(
-                        __(
-                            "We fetched %1 report rows from '%2@%3'.",
-                            $fetched,
-                            $config['username'],
-                            $config['hostname']
-                        )
-                    );
-                } catch (\Exception $e) {
-                    $this->messageManager->addError(
-                        __("We couldn't fetch reports from '%1@%2'.", $config['username'], $config['hostname'])
-                    );
-                    $this->_logger->logException($e);
-                }
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-        }
-        $this->_redirect('*/*/index');
-    }
-
     /**
      * Initialize titles, navigation
      *
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Details.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Details.php
new file mode 100644
index 0000000000000000000000000000000000000000..1587dd78a8fda3f4ed51d675f2847ec5bd4a453e
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Details.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Paypal\Reports;
+
+class Details extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
+{
+    /**
+     * View transaction details action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $rowId = $this->getRequest()->getParam('id');
+        $row = $this->_rowFactory->create()->load($rowId);
+        if (!$row->getId()) {
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        $this->_coreRegistry->register('current_transaction', $row);
+        $this->_initAction();
+        $this->_title->add(__('View Transaction'));
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Paypal\Block\Adminhtml\Settlement\Details',
+                'settlementDetails'
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php
new file mode 100644
index 0000000000000000000000000000000000000000..434a45425c98ddb0b375ffdc2df971fd8b9a23e3
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Fetch.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Paypal\Reports;
+
+class Fetch extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
+{
+    /**
+     * Forced fetch reports action
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function execute()
+    {
+        try {
+            $reports = $this->_settlementFactory->create();
+            /* @var $reports \Magento\Paypal\Model\Report\Settlement */
+            $credentials = $reports->getSftpCredentials();
+            if (empty($credentials)) {
+                throw new \Magento\Framework\Model\Exception(__('We found nothing to fetch because of an empty configuration.'));
+            }
+            foreach ($credentials as $config) {
+                try {
+                    $fetched = $reports->fetchAndSave(
+                        \Magento\Paypal\Model\Report\Settlement::createConnection($config)
+                    );
+                    $this->messageManager->addSuccess(
+                        __(
+                            "We fetched %1 report rows from '%2@%3'.",
+                            $fetched,
+                            $config['username'],
+                            $config['hostname']
+                        )
+                    );
+                } catch (\Exception $e) {
+                    $this->messageManager->addError(
+                        __("We couldn't fetch reports from '%1@%2'.", $config['username'], $config['hostname'])
+                    );
+                    $this->_logger->logException($e);
+                }
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+        }
+        $this->_redirect('*/*/index');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Grid.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..b98711c0784e56b47eb82fab1d2ccbac672868a7
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Paypal\Reports;
+
+class Grid extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
+{
+    /**
+     * Ajax callback for grid actions
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b860d8766d267eb7be50254286b6326b198c32bc
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Adminhtml/Paypal/Reports/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Adminhtml\Paypal\Reports;
+
+class Index extends \Magento\Paypal\Controller\Adminhtml\Paypal\Reports
+{
+    /**
+     * Grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement.php b/app/code/Magento/Paypal/Controller/Billing/Agreement.php
index bb01eb03410736a4af7999fffc5c93da8131499c..8e26b5443ae35fa3f93e3be48aed7ab037c2a315 100644
--- a/app/code/Magento/Paypal/Controller/Billing/Agreement.php
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement.php
@@ -57,19 +57,6 @@ class Agreement extends \Magento\Framework\App\Action\Action
         $this->_title = $title;
     }
 
-    /**
-     * View billing agreements
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Billing Agreements'));
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
     /**
      * Check customer authentication
      *
@@ -87,138 +74,6 @@ class Agreement extends \Magento\Framework\App\Action\Action
         return parent::dispatch($request);
     }
 
-    /**
-     * View billing agreement
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        if (!($agreement = $this->_initAgreement())) {
-            return;
-        }
-        $this->_title->add(__('Billing Agreements'));
-        $this->_title->add(__('Billing Agreement # %1', $agreement->getReferenceId()));
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
-        if ($navigationBlock) {
-            $navigationBlock->setActive('paypal/billing_agreement/');
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Wizard start action
-     *
-     * @return \Zend_Controller_Response_Abstract
-     */
-    public function startWizardAction()
-    {
-        $agreement = $this->_objectManager->create('Magento\Paypal\Model\Billing\Agreement');
-        $paymentCode = $this->getRequest()->getParam('payment_method');
-        if ($paymentCode) {
-            try {
-                $agreement->setStoreId(
-                    $this->_objectManager->get('Magento\Store\Model\StoreManager')->getStore()->getId()
-                )->setMethodCode(
-                    $paymentCode
-                )->setReturnUrl(
-                    $this->_objectManager->create(
-                        'Magento\Framework\UrlInterface'
-                    )->getUrl('*/*/returnWizard', array('payment_method' => $paymentCode))
-                )->setCancelUrl(
-                    $this->_objectManager->create('Magento\Framework\UrlInterface')
-                        ->getUrl('*/*/cancelWizard', array('payment_method' => $paymentCode))
-                );
-
-                return $this->getResponse()->setRedirect($agreement->initToken());
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError(__('We couldn\'t start the billing agreement wizard.'));
-            }
-        }
-        $this->_redirect('*/*/');
-    }
-
-    /**
-     * Wizard return action
-     *
-     * @return void
-     */
-    public function returnWizardAction()
-    {
-        /** @var \Magento\Paypal\Model\Billing\Agreement $agreement */
-        $agreement = $this->_objectManager->create('Magento\Paypal\Model\Billing\Agreement');
-        $paymentCode = $this->getRequest()->getParam('payment_method');
-        $token = $this->getRequest()->getParam('token');
-        if ($token && $paymentCode) {
-            try {
-                $agreement->setStoreId(
-                    $this->_objectManager->get('Magento\Store\Model\StoreManager')->getStore()->getId()
-                )->setToken(
-                    $token
-                )->setMethodCode(
-                    $paymentCode
-                )->setCustomerId(
-                    $this->_getSession()->getCustomerId()
-                )->place();
-
-                $this->messageManager->addSuccess(
-                    __('The billing agreement "%1" has been created.', $agreement->getReferenceId())
-                );
-                $this->_redirect('*/*/view', array('agreement' => $agreement->getId()));
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError(__('We couldn\'t finish the billing agreement wizard.'));
-            }
-            $this->_redirect('*/*/index');
-        }
-    }
-
-    /**
-     * Wizard cancel action
-     *
-     * @return void
-     */
-    public function cancelWizardAction()
-    {
-        $this->_redirect('*/*/index');
-    }
-
-    /**
-     * Cancel action
-     * Set billing agreement status to 'Canceled'
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $agreement = $this->_initAgreement();
-        if (!$agreement) {
-            return;
-        }
-        if ($agreement->canCancel()) {
-            try {
-                $agreement->cancel();
-                $this->messageManager->addNotice(
-                    __('The billing agreement "%1" has been canceled.', $agreement->getReferenceId())
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError(__('We couldn\'t cancel the billing agreement.'));
-            }
-        }
-        $this->_redirect('*/*/view', array('_current' => true));
-    }
-
     /**
      * Init billing agreement model from request
      *
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..21afc8eba9a0607e342e4a1ae735f4247b9ad1cb
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/Cancel.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class Cancel extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * Cancel action
+     * Set billing agreement status to 'Canceled'
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $agreement = $this->_initAgreement();
+        if (!$agreement) {
+            return;
+        }
+        if ($agreement->canCancel()) {
+            try {
+                $agreement->cancel();
+                $this->messageManager->addNotice(
+                    __('The billing agreement "%1" has been canceled.', $agreement->getReferenceId())
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError(__('We couldn\'t cancel the billing agreement.'));
+            }
+        }
+        $this->_redirect('*/*/view', array('_current' => true));
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/CancelWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/CancelWizard.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e18db5d6fb3075217b7bea07881574a153885e7
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/CancelWizard.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class CancelWizard extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * Wizard cancel action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_redirect('*/*/index');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/Index.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb71476601e75fac60df6d71b9857886fa50e8d0
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class Index extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * View billing agreements
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Billing Agreements'));
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
new file mode 100644
index 0000000000000000000000000000000000000000..6804553c979752146795884d985a04857aaaaabd
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/ReturnWizard.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class ReturnWizard extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * Wizard return action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var \Magento\Paypal\Model\Billing\Agreement $agreement */
+        $agreement = $this->_objectManager->create('Magento\Paypal\Model\Billing\Agreement');
+        $paymentCode = $this->getRequest()->getParam('payment_method');
+        $token = $this->getRequest()->getParam('token');
+        if ($token && $paymentCode) {
+            try {
+                $agreement->setStoreId(
+                    $this->_objectManager->get('Magento\Store\Model\StoreManager')->getStore()->getId()
+                )->setToken(
+                    $token
+                )->setMethodCode(
+                    $paymentCode
+                )->setCustomerId(
+                    $this->_getSession()->getCustomerId()
+                )->place();
+
+                $this->messageManager->addSuccess(
+                    __('The billing agreement "%1" has been created.', $agreement->getReferenceId())
+                );
+                $this->_redirect('*/*/view', array('agreement' => $agreement->getId()));
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError(__('We couldn\'t finish the billing agreement wizard.'));
+            }
+            $this->_redirect('*/*/index');
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
new file mode 100644
index 0000000000000000000000000000000000000000..ceabf34db4859b6a5e6e2e9ca21120c78fd18063
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/StartWizard.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class StartWizard extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * Wizard start action
+     *
+     * @return \Zend_Controller_Response_Abstract
+     */
+    public function execute()
+    {
+        $agreement = $this->_objectManager->create('Magento\Paypal\Model\Billing\Agreement');
+        $paymentCode = $this->getRequest()->getParam('payment_method');
+        if ($paymentCode) {
+            try {
+                $agreement->setStoreId(
+                    $this->_objectManager->get('Magento\Store\Model\StoreManager')->getStore()->getId()
+                )->setMethodCode(
+                    $paymentCode
+                )->setReturnUrl(
+                    $this->_objectManager->create(
+                        'Magento\Framework\UrlInterface'
+                    )->getUrl('*/*/returnWizard', array('payment_method' => $paymentCode))
+                )->setCancelUrl(
+                    $this->_objectManager->create('Magento\Framework\UrlInterface')
+                        ->getUrl('*/*/cancelWizard', array('payment_method' => $paymentCode))
+                );
+
+                return $this->getResponse()->setRedirect($agreement->initToken());
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError(__('We couldn\'t start the billing agreement wizard.'));
+            }
+        }
+        $this->_redirect('*/*/');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Billing/Agreement/View.php b/app/code/Magento/Paypal/Controller/Billing/Agreement/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..b60231209844c8c1f06492272f0e746036b2fa6d
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Billing/Agreement/View.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Billing\Agreement;
+
+class View extends \Magento\Paypal\Controller\Billing\Agreement
+{
+    /**
+     * View billing agreement
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!($agreement = $this->_initAgreement())) {
+            return;
+        }
+        $this->_title->add(__('Billing Agreements'));
+        $this->_title->add(__('Billing Agreement # %1', $agreement->getReferenceId()));
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
+        if ($navigationBlock) {
+            $navigationBlock->setActive('paypal/billing_agreement/');
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Bml.php b/app/code/Magento/Paypal/Controller/Bml/Start.php
similarity index 81%
rename from app/code/Magento/Paypal/Controller/Bml.php
rename to app/code/Magento/Paypal/Controller/Bml/Start.php
index fe6c91bba4b00f3e7a2e89755b916fc9de0a9849..f5b5e4eb10eb21c003d9294b2e05e5a55271876b 100644
--- a/app/code/Magento/Paypal/Controller/Bml.php
+++ b/app/code/Magento/Paypal/Controller/Bml/Start.php
@@ -22,20 +22,25 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
  
-namespace Magento\Paypal\Controller;
+namespace Magento\Paypal\Controller\Bml;
 
-class Bml extends \Magento\Framework\App\Action\Action
+class Start extends \Magento\Framework\App\Action\Action
 {
     /**
      * Action for Bill Me Later checkout button (product view and shopping cart pages)
      *
      * @return void
      */
-    public function startAction()
+    public function execute()
     {
-        $this->_forward('start', 'payflowexpress', 'paypal', [
+        $this->_forward(
+            'start',
+            'payflowexpress',
+            'paypal',
+            [
                 'bml' => 1,
                 'button' => $this->getRequest()->getParam('button')
-            ]);
+            ]
+        );
     }
 }
diff --git a/app/code/Magento/Paypal/Controller/Express.php b/app/code/Magento/Paypal/Controller/Express.php
deleted file mode 100644
index bb7b24d90505ea6ff0d5c264f8c566f12738973d..0000000000000000000000000000000000000000
--- a/app/code/Magento/Paypal/Controller/Express.php
+++ /dev/null
@@ -1,113 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Paypal\Controller;
-
-/**
- * Express Checkout Controller
- */
-class Express extends \Magento\Paypal\Controller\Express\AbstractExpress
-{
-    /**
-     * Config mode type
-     *
-     * @var string
-     */
-    protected $_configType = 'Magento\Paypal\Model\Config';
-
-    /**
-     * Config method type
-     *
-     * @var string
-     */
-    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
-
-    /**
-     * Checkout mode type
-     *
-     * @var string
-     */
-    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
-
-    /**
-     * @var \Magento\Core\Helper\Url
-     */
-    protected $_urlHelper;
-
-    /**
-     * @var \Magento\Customer\Helper\Data
-     */
-    protected $_customerHelper;
-
-    /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Sales\Model\QuoteFactory $quoteFactory
-     * @param \Magento\Checkout\Model\Session $checkoutSession
-     * @param \Magento\Sales\Model\OrderFactory $orderFactory
-     * @param \Magento\Paypal\Model\Express\Checkout\Factory $checkoutFactory
-     * @param \Magento\Framework\Session\Generic $paypalSession
-     * @param \Magento\Core\Helper\Url $urlHelper
-     * @param \Magento\Customer\Helper\Data $customerHelper
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Sales\Model\QuoteFactory $quoteFactory,
-        \Magento\Checkout\Model\Session $checkoutSession,
-        \Magento\Sales\Model\OrderFactory $orderFactory,
-        \Magento\Paypal\Model\Express\Checkout\Factory $checkoutFactory,
-        \Magento\Framework\Session\Generic $paypalSession,
-        \Magento\Core\Helper\Url $urlHelper,
-        \Magento\Customer\Helper\Data $customerHelper
-    ) {
-        $this->_customerSession = $customerSession;
-        $this->_urlHelper = $urlHelper;
-        $this->_customerHelper = $customerHelper;
-        parent::__construct(
-            $context,
-            $customerSession,
-            $quoteFactory,
-            $checkoutSession,
-            $orderFactory,
-            $checkoutFactory,
-            $paypalSession
-        );
-    }
-
-    /**
-     * Redirect to login page
-     *
-     * @return void
-     */
-    public function redirectLogin()
-    {
-        $this->_actionFlag->set('', 'no-dispatch', true);
-        $this->_customerSession->setBeforeAuthUrl($this->_redirect->getRefererUrl());
-        $this->getResponse()->setRedirect(
-            $this->_urlHelper->addRequestParam($this->_customerHelper->getLoginUrl(), array('context' => 'checkout'))
-        );
-    }
-}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php
index 6a311d71dec8d52ec679537749e33ddcbcd7e053..2a3c70303b6cc279427e035009ea80da9326445c 100644
--- a/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress.php
@@ -23,10 +23,8 @@
  */
 namespace Magento\Paypal\Controller\Express;
 
-use Magento\Checkout\Model\Type\Onepage;
 use Magento\Framework\App\Action\Action as AppAction;
 use Magento\Checkout\Controller\Express\RedirectLoginInterface;
-use Magento\Paypal\Model\Api\ProcessableException as ApiProcessableException;
 
 /**
  * Abstract Express Checkout Controller
@@ -106,6 +104,16 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      */
     protected $_paypalSession;
 
+    /**
+     * @var \Magento\Core\Helper\Url
+     */
+    protected $_urlHelper;
+
+    /**
+     * @var \Magento\Customer\Helper\Data
+     */
+    protected $_customerHelper;
+
     /**
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Customer\Model\Session $customerSession
@@ -114,6 +122,8 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      * @param \Magento\Sales\Model\OrderFactory $orderFactory
      * @param \Magento\Paypal\Model\Express\Checkout\Factory $checkoutFactory
      * @param \Magento\Framework\Session\Generic $paypalSession
+     * @param \Magento\Core\Helper\Url $urlHelper
+     * @param \Magento\Customer\Helper\Data $customerHelper
      */
     public function __construct(
         \Magento\Framework\App\Action\Context $context,
@@ -122,7 +132,9 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
         \Magento\Checkout\Model\Session $checkoutSession,
         \Magento\Sales\Model\OrderFactory $orderFactory,
         \Magento\Paypal\Model\Express\Checkout\Factory $checkoutFactory,
-        \Magento\Framework\Session\Generic $paypalSession
+        \Magento\Framework\Session\Generic $paypalSession,
+        \Magento\Core\Helper\Url $urlHelper,
+        \Magento\Customer\Helper\Data $customerHelper
     ) {
         $this->_customerSession = $customerSession;
         $this->_quoteFactory = $quoteFactory;
@@ -130,408 +142,13 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
         $this->_orderFactory = $orderFactory;
         $this->_checkoutFactory = $checkoutFactory;
         $this->_paypalSession = $paypalSession;
+        $this->_urlHelper = $urlHelper;
+        $this->_customerHelper = $customerHelper;
         parent::__construct($context);
         $parameters = array('params' => array($this->_configMethod));
         $this->_config = $this->_objectManager->create($this->_configType, $parameters);
     }
 
-    /**
-     * Start Express Checkout by requesting initial token and dispatching customer to PayPal
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        try {
-            $this->_initCheckout();
-
-            if ($this->_getQuote()->getIsMultiShipping()) {
-                $this->_getQuote()->setIsMultiShipping(false);
-                $this->_getQuote()->removeAllAddresses();
-            }
-
-            $customerData = $this->_customerSession->getCustomerDataObject();
-            $quoteCheckoutMethod = $this->_getQuote()->getCheckoutMethod();
-            if ($customerData->getId()) {
-                $this->_checkout->setCustomerWithAddressChange(
-                    $customerData,
-                    $this->_getQuote()->getBillingAddress(),
-                    $this->_getQuote()->getShippingAddress()
-                );
-            } elseif ((!$quoteCheckoutMethod || $quoteCheckoutMethod != Onepage::METHOD_REGISTER)
-                && !$this->_objectManager->get('Magento\Checkout\Helper\Data')->isAllowedGuestCheckout(
-                    $this->_getQuote(),
-                    $this->_getQuote()->getStoreId()
-                )
-            ) {
-
-                $this->messageManager->addNotice(
-                    __('To proceed to Checkout, please log in using your email address.')
-                );
-
-                $this->_objectManager->get('Magento\Checkout\Helper\ExpressRedirect')->redirectLogin($this);
-                $this->_customerSession->setBeforeAuthUrl($this->_url->getUrl('*/*/*', array('_current' => true)));
-
-                return;
-            }
-
-            // billing agreement
-            $isBaRequested = (bool)$this->getRequest()
-                ->getParam(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_TRANSPORT_BILLING_AGREEMENT);
-            if ($customerData->getId()) {
-                $this->_checkout->setIsBillingAgreementRequested($isBaRequested);
-            }
-
-            // Bill Me Later
-            $this->_checkout->setIsBml((bool)$this->getRequest()->getParam('bml'));
-
-            // giropay
-            $this->_checkout->prepareGiropayUrls(
-                $this->_url->getUrl('checkout/onepage/success'),
-                $this->_url->getUrl('paypal/express/cancel'),
-                $this->_url->getUrl('checkout/onepage/success')
-            );
-
-            $button = (bool)$this->getRequest()->getParam(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_BUTTON);
-            $token = $this->_checkout->start(
-                $this->_url->getUrl('*/*/return'),
-                $this->_url->getUrl('*/*/cancel'),
-                $button
-            );
-            $url = $this->_checkout->getRedirectUrl();
-            if ($token && $url) {
-                $this->_initToken($token);
-                $this->getResponse()->setRedirect($url);
-                return;
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t start Express Checkout.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * Return shipping options items for shipping address from request
-     *
-     * @return void
-     */
-    public function shippingOptionsCallbackAction()
-    {
-        try {
-            $quoteId = $this->getRequest()->getParam('quote_id');
-            $this->_quote = $this->_quoteFactory->create()->load($quoteId);
-            $this->_initCheckout();
-            $response = $this->_checkout->getShippingOptionsCallbackResponse($this->getRequest()->getParams());
-            $this->getResponse()->setBody($response);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Cancel Express Checkout
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        try {
-            $this->_initToken(false);
-            // TODO verify if this logic of order cancellation is deprecated
-            // if there is an order - cancel it
-            $orderId = $this->_getCheckoutSession()->getLastOrderId();
-            /** @var \Magento\Sales\Model\Order $order */
-            $order = $orderId ? $this->_orderFactory->create()->load($orderId) : false;
-            if ($order && $order->getId() && $order->getQuoteId() == $this->_getCheckoutSession()->getQuoteId()) {
-                $order->cancel()->save();
-                $this->_getCheckoutSession()
-                    ->unsLastQuoteId()
-                    ->unsLastSuccessQuoteId()
-                    ->unsLastOrderId()
-                    ->unsLastRealOrderId();
-                $this->messageManager->addSuccess(__('Express Checkout and Order have been canceled.'));
-            } else {
-                $this->messageManager->addSuccess(__('Express Checkout has been canceled.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('Unable to cancel Express Checkout'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * Return from PayPal and dispatch customer to order review page
-     *
-     * @return void
-     */
-    public function returnAction()
-    {
-        if ($this->getRequest()->getParam('retry_authorization') == 'true'
-            && is_array($this->_getCheckoutSession()->getPaypalTransactionData())
-        ) {
-            $this->_forward('placeOrder');
-            return;
-        }
-        try {
-            $this->_getCheckoutSession()->unsPaypalTransactionData();
-            $this->_initCheckout();
-            $this->_checkout->returnFromPaypal($this->_initToken());
-            if ($this->_checkout->canSkipOrderReviewStep()) {
-                $this->_forward('placeOrder');
-            } else {
-                $this->_redirect('*/*/review');
-            }
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t process Express Checkout approval.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * Review order after returning from PayPal
-     *
-     * @return void
-     */
-    public function reviewAction()
-    {
-        try {
-            $this->_initCheckout();
-            $this->_checkout->prepareOrderReview($this->_initToken());
-            $this->_view->loadLayout();
-            $this->_view->getLayout()->initMessages();
-            $reviewBlock = $this->_view->getLayout()->getBlock('paypal.express.review');
-            $reviewBlock->setQuote($this->_getQuote());
-            $reviewBlock->getChildBlock('details')->setQuote($this->_getQuote());
-            if ($reviewBlock->getChildBlock('shipping_method')) {
-                $reviewBlock->getChildBlock('shipping_method')->setQuote($this->_getQuote());
-            }
-            $this->_view->renderLayout();
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(
-                __('We can\'t initialize Express Checkout review.')
-            );
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * Dispatch customer back to PayPal for editing payment information
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        try {
-            $this->getResponse()->setRedirect($this->_config->getExpressCheckoutEditUrl($this->_initToken()));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/review');
-        }
-    }
-
-    /**
-     * Update shipping method (combined action for ajax and regular request)
-     *
-     * @return void
-     */
-    public function saveShippingMethodAction()
-    {
-        try {
-            $isAjax = $this->getRequest()->getParam('isAjax');
-            $this->_initCheckout();
-            $this->_checkout->updateShippingMethod($this->getRequest()->getParam('shipping_method'));
-            if ($isAjax) {
-                $this->_view->loadLayout('paypal_express_review_details');
-                $this->getResponse()->setBody(
-                    $this->_view->getLayout()->getBlock('root')->setQuote($this->_getQuote())->toHtml()
-                );
-                return;
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        if ($isAjax) {
-            $this->getResponse()->setBody(
-                '<script type="text/javascript">window.location.href = '
-                . $this->_url->getUrl('*/*/review')
-                . ';</script>'
-            );
-        } else {
-            $this->_redirect('*/*/review');
-        }
-    }
-
-    /**
-     * Update Order (combined action for ajax and regular request)
-     *
-     * @return void
-     */
-    public function updateShippingMethodsAction()
-    {
-        try {
-            $this->_initCheckout();
-            $this->_checkout->prepareOrderReview($this->_initToken());
-            $this->_view->loadLayout('paypal_express_review');
-
-            $this->getResponse()->setBody(
-                $this->_view
-                    ->getLayout()
-                    ->getBlock('express.review.shipping.method')
-                    ->setQuote($this->_getQuote())
-                    ->toHtml()
-            );
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t update shipping method.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->setBody(
-            '<script type="text/javascript">window.location.href = ' . $this->_url->getUrl('*/*/review') . ';</script>'
-        );
-    }
-
-    /**
-     * Submit the order
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function placeOrderAction()
-    {
-        try {
-            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
-            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) {
-                throw new \Magento\Framework\Model\Exception(
-                    __('Please agree to all the terms and conditions before placing the order.')
-                );
-            }
-
-            $this->_initCheckout();
-            $this->_checkout->place($this->_initToken());
-
-            // prepare session to success or cancellation page
-            $this->_getCheckoutSession()->clearHelperData();
-
-            // "last successful quote"
-            $quoteId = $this->_getQuote()->getId();
-            $this->_getCheckoutSession()->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
-
-            // an order may be created
-            $order = $this->_checkout->getOrder();
-            if ($order) {
-                $this->_getCheckoutSession()->setLastOrderId($order->getId())
-                    ->setLastRealOrderId($order->getIncrementId());
-            }
-
-            $this->_eventManager->dispatch(
-                'paypal_express_place_order_success',
-                [
-                    'order' => $order,
-                    'quote' => $this->_getQuote()
-                ]
-            );
-
-            // redirect if PayPal specified some URL (for example, to Giropay bank)
-            $url = $this->_checkout->getRedirectUrl();
-            if ($url) {
-                $this->getResponse()->setRedirect($url);
-                return;
-            }
-            $this->_initToken(false); // no need in token anymore
-            $this->_redirect('checkout/onepage/success');
-            return;
-        } catch (ApiProcessableException $e) {
-            $this->_processPaypalApiError($e);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*/*/review');
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t place the order.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('*/*/review');
-        }
-    }
-
-    /**
-     * Process PayPal API's processable errors
-     *
-     * @param \Magento\Paypal\Model\Api\ProcessableException $exception
-     * @return void
-     */
-    protected function _processPaypalApiError($exception)
-    {
-        switch ($exception->getCode()) {
-            case ApiProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED:
-            case ApiProcessableException::API_TRANSACTION_EXPIRED:
-                $this->getResponse()->setRedirect(
-                    $this->_getQuote()->getPayment()->getCheckoutRedirectUrl()
-                );
-                break;
-            case ApiProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL:
-                $this->_redirectSameToken();
-                break;
-            case ApiProcessableException::API_UNABLE_TRANSACTION_COMPLETE:
-                if ($this->_config->getPaymentAction() == \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER) {
-                    $paypalTransactionData = $this->_getCheckoutSession()->getPaypalTransactionData();
-                    $this->getResponse()->setRedirect(
-                        $this->_config->getExpressCheckoutOrderUrl($paypalTransactionData['transaction_id'])
-                    );
-                } else {
-                    $this->_redirectSameToken();
-                }
-                break;
-            default:
-                $this->_redirectToCartAndShowError($exception->getUserMessage());
-                break;
-        }
-    }
-
-    /**
-     * Redirect customer back to PayPal with the same token
-     *
-     * @return void
-     */
-    protected function _redirectSameToken()
-    {
-        $token = $this->_initToken();
-        $this->getResponse()->setRedirect(
-            $this->_config->getExpressCheckoutStartUrl($token)
-        );
-    }
-
-    /**
-     * Redirect customer to shopping cart and show error message
-     *
-     * @param string $errorMessage
-     * @return void
-     */
-    protected function _redirectToCartAndShowError($errorMessage)
-    {
-        $this->messageManager->addError($errorMessage);
-        $this->_redirect('checkout/cart');
-    }
-
     /**
      * Instantiate quote and checkout
      *
@@ -563,7 +180,7 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      * Combined getter/setter
      *
      * @param string|null $setToken
-     * @return \Magento\Paypal\Controller\Express|string
+     * @return $this|string
      * @throws \Magento\Framework\Model\Exception
      */
     protected function _initToken($setToken = null)
@@ -596,7 +213,7 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      *
      * @return \Magento\Framework\Session\Generic
      */
-    private function _getSession()
+    protected function _getSession()
     {
         return $this->_paypalSession;
     }
@@ -606,7 +223,7 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      *
      * @return \Magento\Checkout\Model\Session
      */
-    private function _getCheckoutSession()
+    protected function _getCheckoutSession()
     {
         return $this->_checkoutSession;
     }
@@ -616,7 +233,7 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
      *
      * @return \Magento\Sales\Model\Quote
      */
-    private function _getQuote()
+    protected function _getQuote()
     {
         if (!$this->_quote) {
             $this->_quote = $this->_getCheckoutSession()->getQuote();
@@ -659,4 +276,19 @@ abstract class AbstractExpress extends AppAction implements RedirectLoginInterfa
     {
         return 'start';
     }
+
+
+    /**
+     * Redirect to login page
+     *
+     * @return void
+     */
+    public function redirectLogin()
+    {
+        $this->_actionFlag->set('', 'no-dispatch', true);
+        $this->_customerSession->setBeforeAuthUrl($this->_redirect->getRefererUrl());
+        $this->getResponse()->setRedirect(
+            $this->_urlHelper->addRequestParam($this->_customerHelper->getLoginUrl(), array('context' => 'checkout'))
+        );
+    }
 }
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..da794fc7771c7c98966be8f1f050679a5d2aa283
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Cancel.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class Cancel extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Cancel Express Checkout
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initToken(false);
+            // TODO verify if this logic of order cancellation is deprecated
+            // if there is an order - cancel it
+            $orderId = $this->_getCheckoutSession()->getLastOrderId();
+            /** @var \Magento\Sales\Model\Order $order */
+            $order = $orderId ? $this->_orderFactory->create()->load($orderId) : false;
+            if ($order && $order->getId() && $order->getQuoteId() == $this->_getCheckoutSession()->getQuoteId()) {
+                $order->cancel()->save();
+                $this->_getCheckoutSession()
+                    ->unsLastQuoteId()
+                    ->unsLastSuccessQuoteId()
+                    ->unsLastOrderId()
+                    ->unsLastRealOrderId();
+                $this->messageManager->addSuccess(__('Express Checkout and Order have been canceled.'));
+            } else {
+                $this->messageManager->addSuccess(__('Express Checkout has been canceled.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('Unable to cancel Express Checkout'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Edit.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..94fdd5dddabdcc4fc7032c8ca59cbf710fab28f0
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Edit.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class Edit extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Dispatch customer back to PayPal for editing payment information
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getResponse()->setRedirect($this->_config->getExpressCheckoutEditUrl($this->_initToken()));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/review');
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..58bbe4fdc027423951b3ad72eb692ce5df219c96
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/PlaceOrder.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+use Magento\Paypal\Model\Api\ProcessableException as ApiProcessableException;
+
+class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Submit the order
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function execute()
+    {
+        try {
+            $agreementsValidator = $this->_objectManager->get('Magento\Checkout\Model\Agreements\AgreementsValidator');
+            if (!$agreementsValidator->isValid(array_keys($this->getRequest()->getPost('agreement', [])))) {
+                throw new \Magento\Framework\Model\Exception(
+                    __('Please agree to all the terms and conditions before placing the order.')
+                );
+            }
+
+            $this->_initCheckout();
+            $this->_checkout->place($this->_initToken());
+
+            // prepare session to success or cancellation page
+            $this->_getCheckoutSession()->clearHelperData();
+
+            // "last successful quote"
+            $quoteId = $this->_getQuote()->getId();
+            $this->_getCheckoutSession()->setLastQuoteId($quoteId)->setLastSuccessQuoteId($quoteId);
+
+            // an order may be created
+            $order = $this->_checkout->getOrder();
+            if ($order) {
+                $this->_getCheckoutSession()->setLastOrderId($order->getId())
+                    ->setLastRealOrderId($order->getIncrementId());
+            }
+
+            $this->_eventManager->dispatch(
+                'paypal_express_place_order_success',
+                [
+                    'order' => $order,
+                    'quote' => $this->_getQuote()
+                ]
+            );
+
+            // redirect if PayPal specified some URL (for example, to Giropay bank)
+            $url = $this->_checkout->getRedirectUrl();
+            if ($url) {
+                $this->getResponse()->setRedirect($url);
+                return;
+            }
+            $this->_initToken(false); // no need in token anymore
+            $this->_redirect('checkout/onepage/success');
+            return;
+        } catch (ApiProcessableException $e) {
+            $this->_processPaypalApiError($e);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*/*/review');
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t place the order.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('*/*/review');
+        }
+    }
+
+    /**
+     * Process PayPal API's processable errors
+     *
+     * @param \Magento\Paypal\Model\Api\ProcessableException $exception
+     * @return void
+     */
+    protected function _processPaypalApiError($exception)
+    {
+        switch ($exception->getCode()) {
+            case ApiProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED:
+            case ApiProcessableException::API_TRANSACTION_EXPIRED:
+                $this->getResponse()->setRedirect(
+                    $this->_getQuote()->getPayment()->getCheckoutRedirectUrl()
+                );
+                break;
+            case ApiProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL:
+                $this->_redirectSameToken();
+                break;
+            case ApiProcessableException::API_UNABLE_TRANSACTION_COMPLETE:
+                if ($this->_config->getPaymentAction() == \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER) {
+                    $paypalTransactionData = $this->_getCheckoutSession()->getPaypalTransactionData();
+                    $this->getResponse()->setRedirect(
+                        $this->_config->getExpressCheckoutOrderUrl($paypalTransactionData['transaction_id'])
+                    );
+                } else {
+                    $this->_redirectSameToken();
+                }
+                break;
+            default:
+                $this->_redirectToCartAndShowError($exception->getUserMessage());
+                break;
+        }
+    }
+
+    /**
+     * Redirect customer back to PayPal with the same token
+     *
+     * @return void
+     */
+    protected function _redirectSameToken()
+    {
+        $token = $this->_initToken();
+        $this->getResponse()->setRedirect(
+            $this->_config->getExpressCheckoutStartUrl($token)
+        );
+    }
+
+    /**
+     * Redirect customer to shopping cart and show error message
+     *
+     * @param string $errorMessage
+     * @return void
+     */
+    protected function _redirectToCartAndShowError($errorMessage)
+    {
+        $this->messageManager->addError($errorMessage);
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..5354aee27583e74f79d2e111d92f4ccee39836bc
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ReturnAction.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class ReturnAction extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Return from PayPal and dispatch customer to order review page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('retry_authorization') == 'true'
+            && is_array($this->_getCheckoutSession()->getPaypalTransactionData())
+        ) {
+            $this->_forward('placeOrder');
+            return;
+        }
+        try {
+            $this->_getCheckoutSession()->unsPaypalTransactionData();
+            $this->_initCheckout();
+            $this->_checkout->returnFromPaypal($this->_initToken());
+            if ($this->_checkout->canSkipOrderReviewStep()) {
+                $this->_forward('placeOrder');
+            } else {
+                $this->_redirect('*/*/review');
+            }
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t process Express Checkout approval.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
new file mode 100644
index 0000000000000000000000000000000000000000..54f1d67c9b11b9b3c89355662df47517dcb01259
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Review.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class Review extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Review order after returning from PayPal
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initCheckout();
+            $this->_checkout->prepareOrderReview($this->_initToken());
+            $this->_view->loadLayout();
+            $this->_view->getLayout()->initMessages();
+            $reviewBlock = $this->_view->getLayout()->getBlock('paypal.express.review');
+            $reviewBlock->setQuote($this->_getQuote());
+            $reviewBlock->getChildBlock('details')->setQuote($this->_getQuote());
+            if ($reviewBlock->getChildBlock('shipping_method')) {
+                $reviewBlock->getChildBlock('shipping_method')->setQuote($this->_getQuote());
+            }
+            $this->_view->renderLayout();
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(
+                __('We can\'t initialize Express Checkout review.')
+            );
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..a3135ef50fe349ba3606e4558ca887682a9110d4
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/SaveShippingMethod.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Update shipping method (combined action for ajax and regular request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $isAjax = $this->getRequest()->getParam('isAjax');
+            $this->_initCheckout();
+            $this->_checkout->updateShippingMethod($this->getRequest()->getParam('shipping_method'));
+            if ($isAjax) {
+                $this->_view->loadLayout('paypal_express_review_details');
+                $this->getResponse()->setBody(
+                    $this->_view->getLayout()->getBlock('root')->setQuote($this->_getQuote())->toHtml()
+                );
+                return;
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t update shipping method.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        if ($isAjax) {
+            $this->getResponse()->setBody(
+                '<script type="text/javascript">window.location.href = '
+                . $this->_url->getUrl('*/*/review')
+                . ';</script>'
+            );
+        } else {
+            $this->_redirect('*/*/review');
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
new file mode 100644
index 0000000000000000000000000000000000000000..6e5801402cce1533650f50fba5ee8dc887849a6d
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/ShippingOptionsCallback.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class ShippingOptionsCallback extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Return shipping options items for shipping address from request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $quoteId = $this->getRequest()->getParam('quote_id');
+            $this->_quote = $this->_quoteFactory->create()->load($quoteId);
+            $this->_initCheckout();
+            $response = $this->_checkout->getShippingOptionsCallbackResponse($this->getRequest()->getParams());
+            $this->getResponse()->setBody($response);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..dafea10a26355efb0ff946c0d5554c7a00f2c4e2
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/Start.php
@@ -0,0 +1,109 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+use \Magento\Checkout\Model\Type\Onepage;
+
+class Start extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Start Express Checkout by requesting initial token and dispatching customer to PayPal
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initCheckout();
+
+            if ($this->_getQuote()->getIsMultiShipping()) {
+                $this->_getQuote()->setIsMultiShipping(false);
+                $this->_getQuote()->removeAllAddresses();
+            }
+
+            $customerData = $this->_customerSession->getCustomerDataObject();
+            $quoteCheckoutMethod = $this->_getQuote()->getCheckoutMethod();
+            if ($customerData->getId()) {
+                $this->_checkout->setCustomerWithAddressChange(
+                    $customerData,
+                    $this->_getQuote()->getBillingAddress(),
+                    $this->_getQuote()->getShippingAddress()
+                );
+            } elseif ((!$quoteCheckoutMethod || $quoteCheckoutMethod != Onepage::METHOD_REGISTER)
+                && !$this->_objectManager->get('Magento\Checkout\Helper\Data')->isAllowedGuestCheckout(
+                    $this->_getQuote(),
+                    $this->_getQuote()->getStoreId()
+                )
+            ) {
+
+                $this->messageManager->addNotice(
+                    __('To proceed to Checkout, please log in using your email address.')
+                );
+
+                $this->_objectManager->get('Magento\Checkout\Helper\ExpressRedirect')->redirectLogin($this);
+                $this->_customerSession->setBeforeAuthUrl($this->_url->getUrl('*/*/*', array('_current' => true)));
+
+                return;
+            }
+
+            // billing agreement
+            $isBaRequested = (bool)$this->getRequest()
+                ->getParam(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_TRANSPORT_BILLING_AGREEMENT);
+            if ($customerData->getId()) {
+                $this->_checkout->setIsBillingAgreementRequested($isBaRequested);
+            }
+
+            // Bill Me Later
+            $this->_checkout->setIsBml((bool)$this->getRequest()->getParam('bml'));
+
+            // giropay
+            $this->_checkout->prepareGiropayUrls(
+                $this->_url->getUrl('checkout/onepage/success'),
+                $this->_url->getUrl('paypal/express/cancel'),
+                $this->_url->getUrl('checkout/onepage/success')
+            );
+
+            $button = (bool)$this->getRequest()->getParam(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_BUTTON);
+            $token = $this->_checkout->start(
+                $this->_url->getUrl('*/*/return'),
+                $this->_url->getUrl('*/*/cancel'),
+                $button
+            );
+            $url = $this->_checkout->getRedirectUrl();
+            if ($token && $url) {
+                $this->_initToken($token);
+                $this->getResponse()->setRedirect($url);
+                return;
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t start Express Checkout.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
new file mode 100644
index 0000000000000000000000000000000000000000..d2152c11bcc6bfc77c091fe96589219a29fba4d0
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/AbstractExpress/UpdateShippingMethods.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express\AbstractExpress;
+
+class UpdateShippingMethods extends \Magento\Paypal\Controller\Express\AbstractExpress
+{
+    /**
+     * Update Order (combined action for ajax and regular request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_initCheckout();
+            $this->_checkout->prepareOrderReview($this->_initToken());
+            $this->_view->loadLayout('paypal_express_review');
+
+            $this->getResponse()->setBody(
+                $this->_view
+                    ->getLayout()
+                    ->getBlock('express.review.shipping.method')
+                    ->setQuote($this->_getQuote())
+                    ->toHtml()
+            );
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t update shipping method.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->setBody(
+            '<script type="text/javascript">window.location.href = ' . $this->_url->getUrl('*/*/review') . ';</script>'
+        );
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/Cancel.php b/app/code/Magento/Paypal/Controller/Express/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7d02ba8d41bbc94281bf5224bb992a931cd38df
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/Cancel.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class Cancel extends \Magento\Paypal\Controller\Express\AbstractExpress\Cancel
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/Edit.php b/app/code/Magento/Paypal/Controller/Express/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..084ff56c39a67acee68930ac50afee023b070eb0
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/Edit.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class Edit extends \Magento\Paypal\Controller\Express\AbstractExpress\Edit
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/lib/internal/Magento/Framework/App/Router/AbstractRouter.php b/app/code/Magento/Paypal/Controller/Express/PlaceOrder.php
similarity index 64%
rename from lib/internal/Magento/Framework/App/Router/AbstractRouter.php
rename to app/code/Magento/Paypal/Controller/Express/PlaceOrder.php
index da1539dee6647a975887e54e45159c6909b0b8cf..8db4f9f5107198753131ae944a92f0167cdfb811 100644
--- a/lib/internal/Magento/Framework/App/Router/AbstractRouter.php
+++ b/app/code/Magento/Paypal/Controller/Express/PlaceOrder.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Abstract application router
  *
  * Magento
  *
@@ -23,27 +22,28 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Framework\App\Router;
+namespace Magento\Paypal\Controller\Express;
 
-use Magento\Framework\App\ActionFactory;
-
-abstract class AbstractRouter implements \Magento\Framework\App\RouterInterface
+class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress\PlaceOrder
 {
     /**
-     * @var \Magento\Framework\App\FrontController
+     * Config mode type
+     *
+     * @var string
      */
-    protected $_front;
+    protected $_configType = 'Magento\Paypal\Model\Config';
 
     /**
-     * @var \Magento\Framework\App\ActionFactory
+     * Config method type
+     *
+     * @var string
      */
-    protected $_actionFactory;
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
 
     /**
-     * @param \Magento\Framework\App\ActionFactory $actionFactory
+     * Checkout mode type
+     *
+     * @var string
      */
-    public function __construct(ActionFactory $actionFactory)
-    {
-        $this->_actionFactory = $actionFactory;
-    }
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
 }
diff --git a/app/code/Magento/Paypal/Controller/Express/ReturnAction.php b/app/code/Magento/Paypal/Controller/Express/ReturnAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..555f430740207ecf9d732449fba2e3bcf12235a8
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/ReturnAction.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class ReturnAction extends \Magento\Paypal\Controller\Express\AbstractExpress\ReturnAction
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/Review.php b/app/code/Magento/Paypal/Controller/Express/Review.php
new file mode 100644
index 0000000000000000000000000000000000000000..2b3310abbaca262f67f1506764dc3a4ebd7f3780
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/Review.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class Review extends \Magento\Paypal\Controller\Express\AbstractExpress\Review
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Express/SaveShippingMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..2dc407ef3f932ab5cbb5a425af17e3e0cddbcd8e
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/SaveShippingMethod.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpress\SaveShippingMethod
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/ShippingOptionsCallback.php b/app/code/Magento/Paypal/Controller/Express/ShippingOptionsCallback.php
new file mode 100644
index 0000000000000000000000000000000000000000..a33739ef43c10d51a0c83a2a2da36f603656fa4d
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/ShippingOptionsCallback.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class ShippingOptionsCallback extends \Magento\Paypal\Controller\Express\AbstractExpress\ShippingOptionsCallback
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/Start.php b/app/code/Magento/Paypal/Controller/Express/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..10d020ea5d7178fc94504bfb3bab3dc331f35ab3
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/Start.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Express/UpdateShippingMethods.php b/app/code/Magento/Paypal/Controller/Express/UpdateShippingMethods.php
new file mode 100644
index 0000000000000000000000000000000000000000..e84e26054e35c5ffea71bde5c71d6b1814a4d86f
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Express/UpdateShippingMethods.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class UpdateShippingMethods extends \Magento\Paypal\Controller\Express\AbstractExpress\UpdateShippingMethods
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\Express\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Hostedpro.php b/app/code/Magento/Paypal/Controller/Hostedpro/Cancel.php
similarity index 74%
rename from app/code/Magento/Paypal/Controller/Hostedpro.php
rename to app/code/Magento/Paypal/Controller/Hostedpro/Cancel.php
index 2ceaaa16a118a6ce4ed52be79ec35c93917d2c4f..ebfbd6c01351f5f723a6457e0abb7258cf3a3bfc 100644
--- a/app/code/Magento/Paypal/Controller/Hostedpro.php
+++ b/app/code/Magento/Paypal/Controller/Hostedpro/Cancel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Paypal\Controller;
+namespace Magento\Paypal\Controller\Hostedpro;
 
-/**
- * Hosted Pro Checkout Controller
- *
- * @author     Magento Core Team <core@magentocommerce.com>
- */
-class Hostedpro extends \Magento\Framework\App\Action\Action
+class Cancel extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Checkout\Model\Session
@@ -39,24 +35,30 @@ class Hostedpro extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Checkout\Model\Session $session
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Checkout\Model\Session $session)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Checkout\Model\Session $session
+    ) {
         parent::__construct($context);
         $this->_session = $session;
     }
 
     /**
-     * When a customer return to website from gateway.
+     * Cancel order, return quote to customer
      *
-     * @return void
+     * @param string $errorMsg
+     * @return false|string
      */
-    public function returnAction()
+    protected function _cancelPayment($errorMsg = '')
     {
-        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
-        //TODO: some actions with order
-        if ($session->getLastRealOrderId()) {
-            $this->_redirect('checkout/onepage/success');
+        $gotoSection = false;
+        $helper = $this->_objectManager->get('Magento\Paypal\Helper\Checkout');
+        $helper->cancelCurrentOrder($errorMsg);
+        if ($this->_session->restoreQuote()) {
+            $gotoSection = 'payment';
         }
+
+        return $gotoSection;
     }
 
     /**
@@ -64,7 +66,7 @@ class Hostedpro extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function cancelAction()
+    public function execute()
     {
         $this->_view->loadLayout(false);
         $gotoSection = $this->_cancelPayment();
@@ -73,22 +75,4 @@ class Hostedpro extends \Magento\Framework\App\Action\Action
         //TODO: clarify return logic whether customer will be returned in iframe or in parent window
         $this->_view->renderLayout();
     }
-
-    /**
-     * Cancel order, return quote to customer
-     *
-     * @param string $errorMsg
-     * @return false|string
-     */
-    protected function _cancelPayment($errorMsg = '')
-    {
-        $gotoSection = false;
-        $helper = $this->_objectManager->get('Magento\Paypal\Helper\Checkout');
-        $helper->cancelCurrentOrder($errorMsg);
-        if ($this->_session->restoreQuote()) {
-            $gotoSection = 'payment';
-        }
-
-        return $gotoSection;
-    }
 }
diff --git a/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php b/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c7bb38e47fb7404f7b25b5f2cc9cc265041bf01
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Hostedpro/ReturnAction.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Hostedpro;
+
+class ReturnAction extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * When a customer return to website from gateway.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
+        //TODO: some actions with order
+        if ($session->getLastRealOrderId()) {
+            $this->_redirect('checkout/onepage/success');
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Ipn.php b/app/code/Magento/Paypal/Controller/Ipn/Index.php
similarity index 91%
rename from app/code/Magento/Paypal/Controller/Ipn.php
rename to app/code/Magento/Paypal/Controller/Ipn/Index.php
index a2e5eed1eba25eff344c945551ee8cb1145b3a31..6376122263a656d38e210f734422c19c3577fe75 100644
--- a/app/code/Magento/Paypal/Controller/Ipn.php
+++ b/app/code/Magento/Paypal/Controller/Ipn/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,12 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Paypal\Controller;
+namespace Magento\Paypal\Controller\Ipn;
 
-/**
- * Unified IPN controller for all supported PayPal methods
- */
-class Ipn extends \Magento\Framework\App\Action\Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Framework\Logger
@@ -58,7 +56,7 @@ class Ipn extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         if (!$this->getRequest()->isPost()) {
             return;
diff --git a/app/code/Magento/Paypal/Controller/Payflow.php b/app/code/Magento/Paypal/Controller/Payflow.php
index fef57e0f7f58fc0195b02aa206c96da9c55091d8..aaf1fe49d290ee7380e0da62a120ed5917b5185a 100644
--- a/app/code/Magento/Paypal/Controller/Payflow.php
+++ b/app/code/Magento/Paypal/Controller/Payflow.php
@@ -83,83 +83,6 @@ class Payflow extends \Magento\Framework\App\Action\Action
         parent::__construct($context);
     }
 
-    /**
-     * When a customer cancel payment from payflow gateway.
-     *
-     * @return void
-     */
-    public function cancelPaymentAction()
-    {
-        $this->_view->loadLayout(false);
-        $gotoSection = $this->_cancelPayment();
-        $redirectBlock = $this->_view->getLayout()->getBlock($this->_redirectBlockName);
-        $redirectBlock->setGotoSection($gotoSection);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * When a customer return to website from payflow gateway.
-     *
-     * @return void
-     */
-    public function returnUrlAction()
-    {
-        $this->_view->loadLayout(false);
-        $redirectBlock = $this->_view->getLayout()->getBlock($this->_redirectBlockName);
-
-        if ($this->_checkoutSession->getLastRealOrderId()) {
-            $order = $this->_orderFactory->create()->loadByIncrementId($this->_checkoutSession->getLastRealOrderId());
-
-            if ($order && $order->getIncrementId() == $this->_checkoutSession->getLastRealOrderId()) {
-                $allowedOrderStates = array(
-                    \Magento\Sales\Model\Order::STATE_PROCESSING,
-                    \Magento\Sales\Model\Order::STATE_COMPLETE
-                );
-                if (in_array($order->getState(), $allowedOrderStates)) {
-                    $this->_checkoutSession->unsLastRealOrderId();
-                    $redirectBlock->setGotoSuccessPage(true);
-                } else {
-                    $gotoSection = $this->_cancelPayment(strval($this->getRequest()->getParam('RESPMSG')));
-                    $redirectBlock->setGotoSection($gotoSection);
-                    $redirectBlock->setErrorMsg(__('Your payment has been declined. Please try again.'));
-                }
-            }
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Submit transaction to Payflow getaway into iframe
-     *
-     * @return void
-     */
-    public function formAction()
-    {
-        $this->getResponse()->setHeader('P3P', 'CP="CAO PSA OUR"');
-        $this->_view->loadLayout(false)->renderLayout();
-        $layout = $this->_view->getLayout();
-    }
-
-    /**
-     * Get response from PayPal by silent post method
-     *
-     * @return void
-     */
-    public function silentPostAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if (isset($data['INVNUM'])) {
-            /** @var $paymentModel \Magento\Paypal\Model\Payflowlink */
-            $paymentModel = $this->_payflowModelFactory->create();
-            try {
-                $paymentModel->process($data);
-            } catch (\Exception $e) {
-                $this->_logger->logException($e);
-            }
-        }
-    }
-
     /**
      * Cancel order, return quote to customer
      *
diff --git a/app/code/Magento/Paypal/Controller/Payflow/CancelPayment.php b/app/code/Magento/Paypal/Controller/Payflow/CancelPayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..a250d3ea55994c1c07df56eaa78386890690b433
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflow/CancelPayment.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflow;
+
+class CancelPayment extends \Magento\Paypal\Controller\Payflow
+{
+    /**
+     * When a customer cancel payment from payflow gateway.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $gotoSection = $this->_cancelPayment();
+        $redirectBlock = $this->_view->getLayout()->getBlock($this->_redirectBlockName);
+        $redirectBlock->setGotoSection($gotoSection);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflow/Form.php b/app/code/Magento/Paypal/Controller/Payflow/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..98f89d052c99117a7fc6cdff199bb9f86a7002b7
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflow/Form.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflow;
+
+class Form extends \Magento\Paypal\Controller\Payflow
+{
+    /**
+     * Submit transaction to Payflow getaway into iframe
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('P3P', 'CP="CAO PSA OUR"');
+        $this->_view->loadLayout(false)->renderLayout();
+        $layout = $this->_view->getLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php
new file mode 100644
index 0000000000000000000000000000000000000000..89fc77acbae52d5df5d17e7c3605c6115070f2ec
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflow/ReturnUrl.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflow;
+
+class ReturnUrl extends \Magento\Paypal\Controller\Payflow
+{
+    /**
+     * When a customer return to website from payflow gateway.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $redirectBlock = $this->_view->getLayout()->getBlock($this->_redirectBlockName);
+
+        if ($this->_checkoutSession->getLastRealOrderId()) {
+            $order = $this->_orderFactory->create()->loadByIncrementId($this->_checkoutSession->getLastRealOrderId());
+
+            if ($order && $order->getIncrementId() == $this->_checkoutSession->getLastRealOrderId()) {
+                $allowedOrderStates = array(
+                    \Magento\Sales\Model\Order::STATE_PROCESSING,
+                    \Magento\Sales\Model\Order::STATE_COMPLETE
+                );
+                if (in_array($order->getState(), $allowedOrderStates)) {
+                    $this->_checkoutSession->unsLastRealOrderId();
+                    $redirectBlock->setGotoSuccessPage(true);
+                } else {
+                    $gotoSection = $this->_cancelPayment(strval($this->getRequest()->getParam('RESPMSG')));
+                    $redirectBlock->setGotoSection($gotoSection);
+                    $redirectBlock->setErrorMsg(__('Your payment has been declined. Please try again.'));
+                }
+            }
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php b/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..45531ee408f853f7c013a35e87c96b04bc2d0a8e
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflow/SilentPost.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflow;
+
+class SilentPost extends \Magento\Paypal\Controller\Payflow
+{
+    /**
+     * Get response from PayPal by silent post method
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if (isset($data['INVNUM'])) {
+            /** @var $paymentModel \Magento\Paypal\Model\Payflowlink */
+            $paymentModel = $this->_payflowModelFactory->create();
+            try {
+                $paymentModel->process($data);
+            } catch (\Exception $e) {
+                $this->_logger->logException($e);
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowadvanced.php b/app/code/Magento/Paypal/Controller/Payflowadvanced/CancelPayment.php
similarity index 87%
rename from app/code/Magento/Paypal/Controller/Payflowadvanced.php
rename to app/code/Magento/Paypal/Controller/Payflowadvanced/CancelPayment.php
index 144ce723fbf3de3cffeadc0eb80a634b547fd95e..612ec583b568a755d4e123fe1b411acbe119cece 100644
--- a/app/code/Magento/Paypal/Controller/Payflowadvanced.php
+++ b/app/code/Magento/Paypal/Controller/Payflowadvanced/CancelPayment.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,12 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Paypal\Controller;
+namespace Magento\Paypal\Controller\Payflowadvanced;
 
-/**
- * Payflow Advanced Checkout Controller
- */
-class Payflowadvanced extends \Magento\Paypal\Controller\Payflow
+class CancelPayment extends \Magento\Paypal\Controller\Payflow\CancelPayment
 {
     /**
      * Redirect block name
diff --git a/app/code/Magento/Paypal/Controller/Payflowadvanced/Form.php b/app/code/Magento/Paypal/Controller/Payflowadvanced/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..ccf6390266a14e3ea4cb658e61d80813d8af1d6d
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowadvanced/Form.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowadvanced;
+
+class Form extends \Magento\Paypal\Controller\Payflow\Form
+{
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowadvanced/ReturnUrl.php b/app/code/Magento/Paypal/Controller/Payflowadvanced/ReturnUrl.php
new file mode 100644
index 0000000000000000000000000000000000000000..830961ac13f8475b2e18eb68421cdc155ef12c91
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowadvanced/ReturnUrl.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowadvanced;
+
+class ReturnUrl extends \Magento\Paypal\Controller\Payflow\ReturnUrl
+{
+    /**
+     * Redirect block name
+     * @var string
+     */
+    protected $_redirectBlockName = 'payflow.advanced.iframe';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowadvanced/SilentPost.php b/app/code/Magento/Paypal/Controller/Payflowadvanced/SilentPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..a7befc143a4d45d6272a1dad64683b4326b9a4a9
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowadvanced/SilentPost.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowadvanced;
+
+class SilentPost extends \Magento\Paypal\Controller\Payflow\SilentPost
+{
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowbml.php b/app/code/Magento/Paypal/Controller/Payflowbml/Start.php
similarity index 81%
rename from app/code/Magento/Paypal/Controller/Payflowbml.php
rename to app/code/Magento/Paypal/Controller/Payflowbml/Start.php
index 9e165d8bcbc3caa64a3ae6f0335ff396ef29b18d..2e8474966a9ee79efc647c1cca42a0e8670326fa 100644
--- a/app/code/Magento/Paypal/Controller/Payflowbml.php
+++ b/app/code/Magento/Paypal/Controller/Payflowbml/Start.php
@@ -22,20 +22,25 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
  
-namespace Magento\Paypal\Controller;
+namespace Magento\Paypal\Controller\Payflowbml;
 
-class Payflowbml extends \Magento\Framework\App\Action\Action
+class Start extends \Magento\Framework\App\Action\Action
 {
     /**
      * Action for Bill Me Later checkout button (product view and shopping cart pages)
      *
      * @return void
      */
-    public function startAction()
+    public function execute()
     {
-        $this->_forward('start', 'express', 'paypal', [
+        $this->_forward(
+            'start',
+            'express',
+            'paypal',
+            [
                 'bml' => 1,
                 'button' => $this->getRequest()->getParam('button')
-            ]);
+            ]
+        );
     }
 }
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress.php b/app/code/Magento/Paypal/Controller/Payflowexpress/Cancel.php
similarity index 89%
rename from app/code/Magento/Paypal/Controller/Payflowexpress.php
rename to app/code/Magento/Paypal/Controller/Payflowexpress/Cancel.php
index 82b8eb19749b0af2197e8385cc6dab06b9969051..ba3eecebab1719491aaf69d2a785e9d2c9d82759 100644
--- a/app/code/Magento/Paypal/Controller/Payflowexpress.php
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/Cancel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,13 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Paypal\Controller\Payflowexpress;
 
-/**
- * Express Checkout Controller
- */
-namespace Magento\Paypal\Controller;
-
-class Payflowexpress extends \Magento\Paypal\Controller\Express\AbstractExpress
+class Cancel extends \Magento\Paypal\Controller\Express\AbstractExpress\Cancel
 {
     /**
      * Config mode type
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/Edit.php b/app/code/Magento/Paypal/Controller/Payflowexpress/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..6aa590f9998fba87be1e152b6fd5cbdbfa45e098
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/Edit.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class Edit extends \Magento\Paypal\Controller\Express\AbstractExpress\Edit
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/PlaceOrder.php b/app/code/Magento/Paypal/Controller/Payflowexpress/PlaceOrder.php
new file mode 100644
index 0000000000000000000000000000000000000000..210d98418c6298114a0c6215c5ee81c1793deb19
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/PlaceOrder.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class PlaceOrder extends \Magento\Paypal\Controller\Express\AbstractExpress\PlaceOrder
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/ReturnAction.php b/app/code/Magento/Paypal/Controller/Payflowexpress/ReturnAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..d03c78536d09a0431a8844cbd74fa16c98868838
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/ReturnAction.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class ReturnAction extends \Magento\Paypal\Controller\Express\AbstractExpress\ReturnAction
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/Review.php b/app/code/Magento/Paypal/Controller/Payflowexpress/Review.php
new file mode 100644
index 0000000000000000000000000000000000000000..776540fb0877a997a2e92dd95efcbf6937bb7c33
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/Review.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class Review extends \Magento\Paypal\Controller\Express\AbstractExpress\Review
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/SaveShippingMethod.php b/app/code/Magento/Paypal/Controller/Payflowexpress/SaveShippingMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..687c056f4bacd8b6fec57ae2f637e6796158f7de
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/SaveShippingMethod.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class SaveShippingMethod extends \Magento\Paypal\Controller\Express\AbstractExpress\SaveShippingMethod
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/ShippingOptionsCallback.php b/app/code/Magento/Paypal/Controller/Payflowexpress/ShippingOptionsCallback.php
new file mode 100644
index 0000000000000000000000000000000000000000..97c58806734dffa7971a4fa8a1610871b027f9ab
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/ShippingOptionsCallback.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class ShippingOptionsCallback extends \Magento\Paypal\Controller\Express\AbstractExpress\ShippingOptionsCallback
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php b/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..6eb0f9a6e3711d9bc4df6931d958bdff18da1017
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/Start.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class Start extends \Magento\Paypal\Controller\Express\AbstractExpress\Start
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Payflowexpress/UpdateShippingMethods.php b/app/code/Magento/Paypal/Controller/Payflowexpress/UpdateShippingMethods.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd88a9e2ff92fd9bd30fa79fd75c5a87fe0152b3
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Payflowexpress/UpdateShippingMethods.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Payflowexpress;
+
+class UpdateShippingMethods extends \Magento\Paypal\Controller\Express\AbstractExpress\UpdateShippingMethods
+{
+    /**
+     * Config mode type
+     *
+     * @var string
+     */
+    protected $_configType = 'Magento\Paypal\Model\Config';
+
+    /**
+     * Config method type
+     *
+     * @var string
+     */
+    protected $_configMethod = \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS;
+
+    /**
+     * Checkout mode type
+     *
+     * @var string
+     */
+    protected $_checkoutType = 'Magento\Paypal\Model\PayflowExpress\Checkout';
+}
diff --git a/app/code/Magento/Paypal/Controller/Standard.php b/app/code/Magento/Paypal/Controller/Standard.php
deleted file mode 100644
index 0e6ee7f6b7cbe185b433793ba990ac4edd63fb95..0000000000000000000000000000000000000000
--- a/app/code/Magento/Paypal/Controller/Standard.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Paypal\Controller;
-
-use Magento\Sales\Model\Order;
-
-/**
- * Paypal Standard Checkout Controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Standard extends \Magento\Framework\App\Action\Action
-{
-    /**
-     * Order instance
-     *
-     * @var Order
-     */
-    protected $_order;
-
-    /**
-     * Get order
-     *
-     * @return Order
-     */
-    public function getOrder()
-    {
-        return $this->_order;
-    }
-
-    /**
-     * Send expire header to ajax response
-     *
-     * @return void
-     */
-    protected function _expireAjax()
-    {
-        if (!$this->_objectManager->get('Magento\Checkout\Model\Session')->getQuote()->hasItems()) {
-            $this->getResponse()->setHeader('HTTP/1.1', '403 Session Expired');
-            exit;
-        }
-    }
-
-    /**
-     * Get singleton with paypal strandard order transaction information
-     *
-     * @return \Magento\Paypal\Model\Standard
-     */
-    public function getStandard()
-    {
-        return $this->_objectManager->get('Magento\Paypal\Model\Standard');
-    }
-
-    /**
-     * When a customer chooses Paypal on Checkout/Payment page
-     *
-     * @return void
-     */
-    public function redirectAction()
-    {
-        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
-        $session->setPaypalStandardQuoteId($session->getQuoteId());
-        $this->_view->loadLayout(false)->renderLayout();
-        $session->unsQuoteId();
-        $session->unsRedirectUrl();
-    }
-
-    /**
-     * When a customer cancel payment from paypal.
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        /** @var \Magento\Checkout\Model\Session $session */
-        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
-        $session->setQuoteId($session->getPaypalStandardQuoteId(true));
-
-        if ($session->getLastRealOrderId()) {
-            /** @var \Magento\Sales\Model\Order $order */
-            $order = $this->_objectManager->create(
-                'Magento\Sales\Model\Order'
-            )->loadByIncrementId(
-                $session->getLastRealOrderId()
-            );
-            if ($order->getId()) {
-                $order->cancel()->save();
-            }
-            $session->restoreQuote();
-        }
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * When paypal returns
-     * The order information at this point is in POST
-     * variables.  However, you don't want to "process" the order until you
-     * get validation from the IPN.
-     *
-     * @return void
-     */
-    public function successAction()
-    {
-        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
-        $session->setQuoteId($session->getPaypalStandardQuoteId(true));
-        $session->getQuote()->setIsActive(false)->save();
-        $this->_redirect('checkout/onepage/success', array('_secure' => true));
-    }
-}
diff --git a/app/code/Magento/Paypal/Controller/Standard/Cancel.php b/app/code/Magento/Paypal/Controller/Standard/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e79520d7e10f9dde6791eb2d930a27dfa172ebf
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Standard/Cancel.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Standard;
+
+use \Magento\Sales\Model\Order;
+
+class Cancel extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * When a customer cancel payment from paypal.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var \Magento\Checkout\Model\Session $session */
+        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
+        $session->setQuoteId($session->getPaypalStandardQuoteId(true));
+
+        if ($session->getLastRealOrderId()) {
+            /** @var \Magento\Sales\Model\Order $order */
+            $order = $this->_objectManager->create(
+                'Magento\Sales\Model\Order'
+            )->loadByIncrementId(
+                $session->getLastRealOrderId()
+            );
+            if ($order->getId()) {
+                $order->cancel()->save();
+            }
+            $session->restoreQuote();
+        }
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Standard/Redirect.php b/app/code/Magento/Paypal/Controller/Standard/Redirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..646ab995304b3c3debd9ce03ff49fe64ac397c69
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Standard/Redirect.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Standard;
+
+class Redirect extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * When a customer chooses Paypal on Checkout/Payment page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
+        $session->setPaypalStandardQuoteId($session->getQuoteId());
+        $this->_view->loadLayout(false)->renderLayout();
+        $session->unsQuoteId();
+        $session->unsRedirectUrl();
+    }
+}
diff --git a/app/code/Magento/Paypal/Controller/Standard/Success.php b/app/code/Magento/Paypal/Controller/Standard/Success.php
new file mode 100644
index 0000000000000000000000000000000000000000..17804d5516759daf737a48d9b002c0820681f214
--- /dev/null
+++ b/app/code/Magento/Paypal/Controller/Standard/Success.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Standard;
+
+class Success extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * When paypal returns
+     * The order information at this point is in POST
+     * variables.  However, you don't want to "process" the order until you
+     * get validation from the IPN.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
+        $session->setQuoteId($session->getPaypalStandardQuoteId(true));
+        $session->getQuote()->setIsActive(false)->save();
+        $this->_redirect('checkout/onepage/success', array('_secure' => true));
+    }
+}
diff --git a/app/code/Magento/Paypal/etc/di.xml b/app/code/Magento/Paypal/etc/di.xml
index ea1b152a85dad12113f1134aaa03661b5c4f0725..7acdb23682d0aae630d5ab4dcbf70808367503a4 100644
--- a/app/code/Magento/Paypal/etc/di.xml
+++ b/app/code/Magento/Paypal/etc/di.xml
@@ -36,7 +36,7 @@
             <argument name="instanceName" xsi:type="string">Magento\Paypal\Model\Payflowadvanced</argument>
         </arguments>
     </virtualType>
-    <type name="Magento\Paypal\Controller\Payflowadvanced">
+    <type name="Magento\Paypal\Controller\Payflowadvanced\SilentPost">
         <arguments>
             <argument name="payflowModelFactory" xsi:type="object">Magento\Paypal\Model\PayflowadvancedFactory</argument>
         </arguments>
diff --git a/app/code/Magento/Persistent/Controller/Index.php b/app/code/Magento/Persistent/Controller/Index.php
index 9b14b190d00703cca5da8a9cb9185f2dfdb0ac8f..5203055a409c57e620be0fcc3ca9d6ff60d57fde 100644
--- a/app/code/Magento/Persistent/Controller/Index.php
+++ b/app/code/Magento/Persistent/Controller/Index.php
@@ -97,65 +97,4 @@ class Index extends \Magento\Framework\App\Action\Action
     {
         return $this->_objectManager->get('Magento\Persistent\Helper\Session');
     }
-
-    /**
-     * Unset persistent cookie action
-     *
-     * @return void
-     */
-    public function unsetCookieAction()
-    {
-        if ($this->_getHelper()->isPersistent()) {
-            $this->_cleanup();
-        }
-        $this->_redirect('customer/account/login');
-        return;
-    }
-
-    /**
-     * Revert all persistent data
-     *
-     * @return $this
-     */
-    protected function _cleanup()
-    {
-        $this->_eventManager->dispatch('persistent_session_expired');
-        $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
-        if ($this->_clearCheckoutSession) {
-            $this->_checkoutSession->clearStorage();
-        }
-        $this->_getHelper()->getSession()->removePersistentCookie();
-        return $this;
-    }
-
-    /**
-     * Save onepage checkout method to be register
-     *
-     * @return void
-     */
-    public function saveMethodAction()
-    {
-        if ($this->_getHelper()->isPersistent()) {
-            $this->_getHelper()->getSession()->removePersistentCookie();
-            if (!$this->_customerSession->isLoggedIn()) {
-                $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
-            }
-
-            $this->_persistentObserver->setQuoteGuest();
-        }
-
-        $checkoutUrl = $this->_redirect->getRefererUrl();
-        $this->getResponse()->setRedirect($checkoutUrl . (strpos($checkoutUrl, '?') ? '&' : '?') . 'register');
-    }
-
-    /**
-     * Add appropriate session message and redirect to shopping cart
-     *
-     * @return void
-     */
-    public function expressCheckoutAction()
-    {
-        $this->messageManager->addNotice(__('Your shopping cart has been updated with new prices.'));
-        $this->_redirect('checkout/cart');
-    }
 }
diff --git a/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php b/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php
new file mode 100644
index 0000000000000000000000000000000000000000..42427c303c0bcff8d67b7e494627b89f56cea806
--- /dev/null
+++ b/app/code/Magento/Persistent/Controller/Index/ExpressCheckout.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Persistent\Controller\Index;
+
+class ExpressCheckout extends \Magento\Persistent\Controller\Index
+{
+    /**
+     * Add appropriate session message and redirect to shopping cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->messageManager->addNotice(__('Your shopping cart has been updated with new prices.'));
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Persistent/Controller/Index/SaveMethod.php b/app/code/Magento/Persistent/Controller/Index/SaveMethod.php
new file mode 100644
index 0000000000000000000000000000000000000000..5080a526a7b48372b0741d84cffcbf54e30055b8
--- /dev/null
+++ b/app/code/Magento/Persistent/Controller/Index/SaveMethod.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Persistent\Controller\Index;
+
+class SaveMethod extends \Magento\Persistent\Controller\Index
+{
+    /**
+     * Save onepage checkout method to be register
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getHelper()->isPersistent()) {
+            $this->_getHelper()->getSession()->removePersistentCookie();
+            if (!$this->_customerSession->isLoggedIn()) {
+                $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
+            }
+
+            $this->_persistentObserver->setQuoteGuest();
+        }
+
+        $checkoutUrl = $this->_redirect->getRefererUrl();
+        $this->getResponse()->setRedirect($checkoutUrl . (strpos($checkoutUrl, '?') ? '&' : '?') . 'register');
+    }
+}
diff --git a/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php b/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php
new file mode 100644
index 0000000000000000000000000000000000000000..3fa1806b8c23887448202d8f6a8017e7efd00594
--- /dev/null
+++ b/app/code/Magento/Persistent/Controller/Index/UnsetCookie.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Persistent\Controller\Index;
+
+class UnsetCookie extends \Magento\Persistent\Controller\Index
+{
+    /**
+     * Revert all persistent data
+     *
+     * @return $this
+     */
+    protected function _cleanup()
+    {
+        $this->_eventManager->dispatch('persistent_session_expired');
+        $this->_customerSession->setCustomerId(null)->setCustomerGroupId(null);
+        if ($this->_clearCheckoutSession) {
+            $this->_checkoutSession->clearStorage();
+        }
+        $this->_getHelper()->getSession()->removePersistentCookie();
+        return $this;
+    }
+
+    /**
+     * Unset persistent cookie action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_getHelper()->isPersistent()) {
+            $this->_cleanup();
+        }
+        $this->_redirect('customer/account/login');
+        return;
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Add.php b/app/code/Magento/ProductAlert/Controller/Add.php
index b0aa1dfbbf7b21744baa3151d1bc8aedd81748f5..08813d610b77aa3108d1c5e788ba613ebcdcce62 100644
--- a/app/code/Magento/ProductAlert/Controller/Add.php
+++ b/app/code/Magento/ProductAlert/Controller/Add.php
@@ -23,14 +23,9 @@
  */
 namespace Magento\ProductAlert\Controller;
 
-use Magento\Framework\App\Action\Context;
 use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\Action\Context;
 
-/**
- * ProductAlert controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
 class Add extends \Magento\Framework\App\Action\Action
 {
     /**
@@ -38,22 +33,14 @@ class Add extends \Magento\Framework\App\Action\Action
      */
     protected $_customerSession;
 
-    /**
-     * @var \Magento\Store\Model\StoreManagerInterface
-     */
-    protected $_storeManager;
-
     /**
      * @param Context $context
-     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Customer\Model\Session $customerSession
      */
     public function __construct(
         Context $context,
-        \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Customer\Model\Session $customerSession
     ) {
-        $this->_storeManager = $storeManager;
         $this->_customerSession = $customerSession;
         parent::__construct($context);
     }
@@ -74,116 +61,4 @@ class Add extends \Magento\Framework\App\Action\Action
         }
         return parent::dispatch($request);
     }
-
-    /**
-     * @return void
-     */
-    public function testObserverAction()
-    {
-        $object = new \Magento\Framework\Object();
-        $observer = $this->_objectManager->get('Magento\ProductAlert\Model\Observer');
-        $observer->process($object);
-    }
-
-    /**
-     * @return void
-     */
-    public function priceAction()
-    {
-        $backUrl = $this->getRequest()->getParam(\Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED);
-        $productId = (int)$this->getRequest()->getParam('product_id');
-        if (!$backUrl || !$productId) {
-            $this->_redirect('/');
-            return;
-        }
-
-        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
-        if (!$product->getId()) {
-            /* @var $product \Magento\Catalog\Model\Product */
-            $this->messageManager->addError(__('There are not enough parameters.'));
-            if ($this->_isInternal($backUrl)) {
-                $this->getResponse()->setRedirect($backUrl);
-            } else {
-                $this->_redirect('/');
-            }
-            return;
-        }
-
-        try {
-            $model = $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Price'
-            )->setCustomerId(
-                $this->_customerSession->getCustomerId()
-            )->setProductId(
-                $product->getId()
-            )->setPrice(
-                $product->getFinalPrice()
-            )->setWebsiteId(
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            );
-            $model->save();
-            $this->messageManager->addSuccess(__('You saved the alert subscription.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * @return void
-     */
-    public function stockAction()
-    {
-        $backUrl = $this->getRequest()->getParam(\Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED);
-        $productId = (int)$this->getRequest()->getParam('product_id');
-        if (!$backUrl || !$productId) {
-            $this->_redirect('/');
-            return;
-        }
-
-        if (!($product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId))) {
-            /* @var $product \Magento\Catalog\Model\Product */
-            $this->messageManager->addError(__('There are not enough parameters.'));
-            $this->getResponse()->setRedirect($backUrl);
-            return;
-        }
-
-        try {
-            $model = $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Stock'
-            )->setCustomerId(
-                $this->_customerSession->getCustomerId()
-            )->setProductId(
-                $product->getId()
-            )->setWebsiteId(
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            );
-            $model->save();
-            $this->messageManager->addSuccess(__('Alert subscription has been saved.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Check if URL is internal
-     *
-     * @param string $url
-     * @return bool
-     */
-    protected function _isInternal($url)
-    {
-        if (strpos($url, 'http') === false) {
-            return false;
-        }
-        $currentStore = $this->_storeManager->getStore();
-        return strpos(
-            $url,
-            $currentStore->getBaseUrl()
-        ) === 0 || strpos(
-            $url,
-            $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK, true)
-        ) === 0;
-    }
 }
diff --git a/app/code/Magento/ProductAlert/Controller/Add/Price.php b/app/code/Magento/ProductAlert/Controller/Add/Price.php
new file mode 100644
index 0000000000000000000000000000000000000000..184fa007cfbfd96eb3b08ebd3fb497416b731e01
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Add/Price.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Add;
+
+use Magento\Framework\App\Action\Context;
+
+class Price extends \Magento\ProductAlert\Controller\Add
+{
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $_storeManager;
+
+    /**
+     * @param Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Store\Model\StoreManagerInterface $storeManager
+    ) {
+        $this->_storeManager = $storeManager;
+        parent::__construct($context, $customerSession);
+    }
+
+    /**
+     * Check if URL is internal
+     *
+     * @param string $url
+     * @return bool
+     */
+    protected function _isInternal($url)
+    {
+        if (strpos($url, 'http') === false) {
+            return false;
+        }
+        $currentStore = $this->_storeManager->getStore();
+        return strpos(
+            $url,
+            $currentStore->getBaseUrl()
+        ) === 0 || strpos(
+            $url,
+            $currentStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK, true)
+        ) === 0;
+    }
+
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $backUrl = $this->getRequest()->getParam(\Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED);
+        $productId = (int)$this->getRequest()->getParam('product_id');
+        if (!$backUrl || !$productId) {
+            $this->_redirect('/');
+            return;
+        }
+
+        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+        if (!$product->getId()) {
+            /* @var $product \Magento\Catalog\Model\Product */
+            $this->messageManager->addError(__('There are not enough parameters.'));
+            if ($this->_isInternal($backUrl)) {
+                $this->getResponse()->setRedirect($backUrl);
+            } else {
+                $this->_redirect('/');
+            }
+            return;
+        }
+
+        try {
+            $model = $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Price'
+            )->setCustomerId(
+                $this->_customerSession->getCustomerId()
+            )->setProductId(
+                $product->getId()
+            )->setPrice(
+                $product->getFinalPrice()
+            )->setWebsiteId(
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            );
+            $model->save();
+            $this->messageManager->addSuccess(__('You saved the alert subscription.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Add/Stock.php b/app/code/Magento/ProductAlert/Controller/Add/Stock.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab2eaa59ce59303ac1d8db4f6f99fc888b70b1c1
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Add/Stock.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Add;
+
+class Stock extends \Magento\ProductAlert\Controller\Add
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $backUrl = $this->getRequest()->getParam(\Magento\Framework\App\Action\Action::PARAM_NAME_URL_ENCODED);
+        $productId = (int)$this->getRequest()->getParam('product_id');
+        if (!$backUrl || !$productId) {
+            $this->_redirect('/');
+            return;
+        }
+
+        if (!($product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId))) {
+            /* @var $product \Magento\Catalog\Model\Product */
+            $this->messageManager->addError(__('There are not enough parameters.'));
+            $this->getResponse()->setRedirect($backUrl);
+            return;
+        }
+
+        try {
+            $model = $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Stock'
+            )->setCustomerId(
+                $this->_customerSession->getCustomerId()
+            )->setProductId(
+                $product->getId()
+            )->setWebsiteId(
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            );
+            $model->save();
+            $this->messageManager->addSuccess(__('Alert subscription has been saved.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Add/TestObserver.php b/app/code/Magento/ProductAlert/Controller/Add/TestObserver.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d475824131906067968aec967488002cb8951da
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Add/TestObserver.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Add;
+
+class TestObserver extends \Magento\ProductAlert\Controller\Add
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $object = new \Magento\Framework\Object();
+        $observer = $this->_objectManager->get('Magento\ProductAlert\Model\Observer');
+        $observer->process($object);
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe.php
index 2556f5888b0e038cd141b317e99e3686dd08f042..e3a8a17cb186832fb4c9ba20e5105d919089dfba 100644
--- a/app/code/Magento/ProductAlert/Controller/Unsubscribe.php
+++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe.php
@@ -23,166 +23,6 @@
  */
 namespace Magento\ProductAlert\Controller;
 
-use Magento\Framework\App\RequestInterface;
-use Magento\Framework\App\Action\Context;
-
-/**
- * ProductAlert unsubscribe controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-
-class Unsubscribe extends \Magento\Framework\App\Action\Action
+class Unsubscribe extends Add
 {
-    /**
-     * @var \Magento\Customer\Model\Session
-     */
-    protected $_customerSession;
-
-    /**
-     * @param Context $context
-     * @param \Magento\Customer\Model\Session $customerSession
-     */
-    public function __construct(
-        Context $context,
-        \Magento\Customer\Model\Session $customerSession
-    ) {
-        $this->_customerSession = $customerSession;
-        parent::__construct($context);
-    }
-
-    /**
-     * Check customer authentication for some actions
-     *
-     * @param RequestInterface $request
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function dispatch(RequestInterface $request)
-    {
-        if (!$this->_customerSession->authenticate($this)) {
-            $this->_actionFlag->set('', 'no-dispatch', true);
-            if (!$this->_customerSession->getBeforeUrl()) {
-                $this->_customerSession->setBeforeUrl($this->_redirect->getRefererUrl());
-            }
-        }
-        return parent::dispatch($request);
-    }
-
-    /**
-     * @return void
-     */
-    public function priceAction()
-    {
-        $productId = (int)$this->getRequest()->getParam('product');
-
-        if (!$productId) {
-            $this->_redirect('');
-            return;
-        }
-        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
-        if (!$product->getId() || !$product->isVisibleInCatalog()) {
-            /* @var $product \Magento\Catalog\Model\Product */
-            $this->messageManager->addError(__('We can\'t find the product.'));
-            $this->_redirect('customer/account/');
-            return;
-        }
-
-        try {
-            $model = $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Price'
-            )->setCustomerId(
-                $this->_customerSession->getCustomerId()
-            )->setProductId(
-                $product->getId()
-            )->setWebsiteId(
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            )->loadByParam();
-            if ($model->getId()) {
-                $model->delete();
-            }
-
-            $this->messageManager->addSuccess(__('You deleted the alert subscription.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->getResponse()->setRedirect($product->getProductUrl());
-    }
-
-    /**
-     * @return void
-     */
-    public function priceAllAction()
-    {
-        try {
-            $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Price'
-            )->deleteCustomer(
-                $this->_customerSession->getCustomerId(),
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            );
-            $this->messageManager->addSuccess(__('You will no longer receive price alerts for this product.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->_redirect('customer/account/');
-    }
-
-    /**
-     * @return void
-     */
-    public function stockAction()
-    {
-        $productId = (int)$this->getRequest()->getParam('product');
-
-        if (!$productId) {
-            $this->_redirect('');
-            return;
-        }
-
-        /* @var $product \Magento\Catalog\Model\Product */
-        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
-        if (!$product->getId() || !$product->isVisibleInCatalog()) {
-            $this->messageManager->addError(__('The product was not found.'));
-            $this->_redirect('customer/account/');
-            return;
-        }
-
-        try {
-            $model = $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Stock'
-            )->setCustomerId(
-                $this->_customerSession->getCustomerId()
-            )->setProductId(
-                $product->getId()
-            )->setWebsiteId(
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            )->loadByParam();
-            if ($model->getId()) {
-                $model->delete();
-            }
-            $this->messageManager->addSuccess(__('You will no longer receive stock alerts for this product.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->getResponse()->setRedirect($product->getProductUrl());
-    }
-
-    /**
-     * @return void
-     */
-    public function stockAllAction()
-    {
-        try {
-            $this->_objectManager->create(
-                'Magento\ProductAlert\Model\Stock'
-            )->deleteCustomer(
-                $this->_customerSession->getCustomerId(),
-                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
-            );
-            $this->messageManager->addSuccess(__('You will no longer receive stock alerts.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
-        }
-        $this->_redirect('customer/account/');
-    }
 }
diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php
new file mode 100644
index 0000000000000000000000000000000000000000..2db2e593e51ba398c8464040cbc03ae5e52225e7
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Price.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Unsubscribe;
+
+class Price extends \Magento\ProductAlert\Controller\Unsubscribe
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $productId = (int)$this->getRequest()->getParam('product');
+
+        if (!$productId) {
+            $this->_redirect('');
+            return;
+        }
+        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+        if (!$product->getId() || !$product->isVisibleInCatalog()) {
+            /* @var $product \Magento\Catalog\Model\Product */
+            $this->messageManager->addError(__('We can\'t find the product.'));
+            $this->_redirect('customer/account/');
+            return;
+        }
+
+        try {
+            $model = $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Price'
+            )->setCustomerId(
+                $this->_customerSession->getCustomerId()
+            )->setProductId(
+                $product->getId()
+            )->setWebsiteId(
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            )->loadByParam();
+            if ($model->getId()) {
+                $model->delete();
+            }
+
+            $this->messageManager->addSuccess(__('You deleted the alert subscription.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->getResponse()->setRedirect($product->getProductUrl());
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/PriceAll.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/PriceAll.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0adb85609cfee77c2088c7a56eef2a978cf5c2d
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/PriceAll.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Unsubscribe;
+
+class PriceAll extends \Magento\ProductAlert\Controller\Unsubscribe
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Price'
+            )->deleteCustomer(
+                $this->_customerSession->getCustomerId(),
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            );
+            $this->messageManager->addSuccess(__('You will no longer receive price alerts for this product.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->_redirect('customer/account/');
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e2f59008a017dde63275d7282d4e9945180412f
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/Stock.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Unsubscribe;
+
+class Stock extends \Magento\ProductAlert\Controller\Unsubscribe
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $productId = (int)$this->getRequest()->getParam('product');
+
+        if (!$productId) {
+            $this->_redirect('');
+            return;
+        }
+
+        /* @var $product \Magento\Catalog\Model\Product */
+        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+        if (!$product->getId() || !$product->isVisibleInCatalog()) {
+            $this->messageManager->addError(__('The product was not found.'));
+            $this->_redirect('customer/account/');
+            return;
+        }
+
+        try {
+            $model = $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Stock'
+            )->setCustomerId(
+                $this->_customerSession->getCustomerId()
+            )->setProductId(
+                $product->getId()
+            )->setWebsiteId(
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            )->loadByParam();
+            if ($model->getId()) {
+                $model->delete();
+            }
+            $this->messageManager->addSuccess(__('You will no longer receive stock alerts for this product.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->getResponse()->setRedirect($product->getProductUrl());
+    }
+}
diff --git a/app/code/Magento/ProductAlert/Controller/Unsubscribe/StockAll.php b/app/code/Magento/ProductAlert/Controller/Unsubscribe/StockAll.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd920a5fb5bc908e91020d37f7f69ac99d380673
--- /dev/null
+++ b/app/code/Magento/ProductAlert/Controller/Unsubscribe/StockAll.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\ProductAlert\Controller\Unsubscribe;
+
+class StockAll extends \Magento\ProductAlert\Controller\Unsubscribe
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_objectManager->create(
+                'Magento\ProductAlert\Model\Stock'
+            )->deleteCustomer(
+                $this->_customerSession->getCustomerId(),
+                $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface')->getStore()->getWebsiteId()
+            );
+            $this->messageManager->addSuccess(__('You will no longer receive stock alerts.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Unable to update the alert subscription.'));
+        }
+        $this->_redirect('customer/account/');
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment.php b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment.php
index d557afb76f69a1fa64c0d6e539687b922192df03..c164bd266592e09e85d906b56e46c6aad6ff0a52 100644
--- a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment.php
+++ b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment.php
@@ -49,6 +49,6 @@ class Payment extends \Magento\Backend\Block\Widget\Grid\Container
     {
         $this->_headerText = __('Recurring Billing Payments (beta)');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View.php b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View.php
index bdacd3571aeaf4d89c9974d3321782a2269eac3d..20d04fbb8a585a86637e9c5dd6a0fdcda6ae6cf1 100644
--- a/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View.php
+++ b/app/code/Magento/RecurringPayment/Block/Adminhtml/Payment/View.php
@@ -37,12 +37,12 @@ class View extends \Magento\Backend\Block\Widget\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -57,7 +57,7 @@ class View extends \Magento\Backend\Block\Widget\Container
      */
     protected function _prepareLayout()
     {
-        $this->_addButton(
+        $this->buttonList->add(
             'back',
             array('label' => __('Back'), 'onclick' => "setLocation('{$this->getUrl('*/*/')}')", 'class' => 'back')
         );
@@ -68,7 +68,7 @@ class View extends \Magento\Backend\Block\Widget\Container
         // cancel
         if ($payment->canCancel()) {
             $url = $this->getUrl('*/*/updateState', array('payment' => $payment->getId(), 'action' => 'cancel'));
-            $this->_addButton(
+            $this->buttonList->add(
                 'cancel',
                 array(
                     'label' => __('Cancel'),
@@ -81,7 +81,7 @@ class View extends \Magento\Backend\Block\Widget\Container
         // suspend
         if ($payment->canSuspend()) {
             $url = $this->getUrl('*/*/updateState', array('payment' => $payment->getId(), 'action' => 'suspend'));
-            $this->_addButton(
+            $this->buttonList->add(
                 'suspend',
                 array(
                     'label' => __('Suspend'),
@@ -94,7 +94,7 @@ class View extends \Magento\Backend\Block\Widget\Container
         // activate
         if ($payment->canActivate()) {
             $url = $this->getUrl('*/*/updateState', array('payment' => $payment->getId(), 'action' => 'activate'));
-            $this->_addButton(
+            $this->buttonList->add(
                 'activate',
                 array(
                     'label' => __('Activate'),
@@ -107,7 +107,7 @@ class View extends \Magento\Backend\Block\Widget\Container
         // get update
         if ($payment->canFetchUpdate()) {
             $url = $this->getUrl('*/*/updatePayment', array('payment' => $payment->getId()));
-            $this->_addButton(
+            $this->buttonList->add(
                 'update',
                 array(
                     'label' => __('Get Update'),
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment.php
index 236abecd3f95471e828df2bf5aa97ea1dae7e2ee..f925b94b5adf788cf6eb46c7fdc5c1339534dea3 100644
--- a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment.php
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment.php
@@ -23,9 +23,7 @@
  */
 namespace Magento\RecurringPayment\Controller\Adminhtml;
 
-use Magento\Framework\App\Action\NotFoundException;
 use Magento\Framework\Model\Exception as CoreException;
-use Magento\Customer\Controller\RegistryConstants;
 
 /**
  * Recurring payments view/management controller
@@ -83,163 +81,6 @@ class RecurringPayment extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Recurring payments list
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Recurring Billing Payments'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_RecurringPayment::recurring_payment');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * View recurring payment details
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        try {
-            $this->_title->add(__('Recurring Billing Payments'));
-            $payment = $this->_initPayment();
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_RecurringPayment::recurring_payment');
-            $this->_title->add(__('Payment #%1', $payment->getReferenceId()));
-            $this->_view->renderLayout();
-            return;
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Payments ajax grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        try {
-            $this->_view->loadLayout()->renderLayout();
-            return;
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Payment orders ajax grid
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function ordersAction()
-    {
-        try {
-            $this->_initPayment();
-            $this->_view->loadLayout()->renderLayout();
-        } catch (\Exception $e) {
-            $this->_logger->logException($e);
-            throw new NotFoundException();
-        }
-    }
-
-    /**
-     * Payment state updater action
-     *
-     * @return void
-     */
-    public function updateStateAction()
-    {
-        $payment = null;
-        try {
-            $payment = $this->_initPayment();
-            $action = $this->getRequest()->getParam(self::PARAM_ACTION);
-
-            switch ($action) {
-                case self::ACTION_CANCEL:
-                    $payment->cancel();
-                    break;
-                case self::ACTION_SUSPEND:
-                    $payment->suspend();
-                    break;
-                case self::ACTION_ACTIVATE:
-                    $payment->activate();
-                    break;
-                default:
-                    throw new \Exception(sprintf('Wrong action parameter: %s', $action));
-            }
-            $this->messageManager->addSuccess(__('The payment state has been updated.'));
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We could not update the payment.'));
-            $this->_logger->logException($e);
-        }
-        if ($payment) {
-            $this->_redirect('sales/*/view', array(self::PARAM_PAYMENT => $payment->getId()));
-        } else {
-            $this->_redirect('sales/*/');
-        }
-    }
-
-    /**
-     * Payment information updater action
-     *
-     * @return void
-     */
-    public function updatePaymentAction()
-    {
-        $payment = null;
-        try {
-            $payment = $this->_initPayment();
-            $payment->fetchUpdate();
-            if ($payment->hasDataChanges()) {
-                $payment->save();
-                $this->messageManager->addSuccess(__('You updated the payment.'));
-            } else {
-                $this->messageManager->addNotice(__('The payment has no changes.'));
-            }
-        } catch (CoreException $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We could not update the payment.'));
-            $this->_logger->logException($e);
-        }
-        if ($payment) {
-            $this->_redirect('sales/*/view', array(self::PARAM_PAYMENT => $payment->getId()));
-        } else {
-            $this->_redirect('sales/*/');
-        }
-    }
-
-    /**
-     * Customer grid ajax action
-     *
-     * @return void
-     */
-    public function customerGridAction()
-    {
-        $customerId = (int)$this->getRequest()->getParam(self::PARAM_CUSTOMER_ID);
-
-        if ($customerId) {
-            $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId);
-        }
-
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
     /**
      * Load/set payment
      *
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/CustomerGrid.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/CustomerGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..8489fa01d1ad6a251eccf2b3d6b261955a0e2c3d
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/CustomerGrid.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Customer\Controller\RegistryConstants;
+
+class CustomerGrid extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Customer grid ajax action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $customerId = (int)$this->getRequest()->getParam(self::PARAM_CUSTOMER_ID);
+
+        if ($customerId) {
+            $this->_coreRegistry->register(RegistryConstants::CURRENT_CUSTOMER_ID, $customerId);
+        }
+
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Grid.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..29623e1e7a78162e5ad2659cb97c9cd73ee3f86b
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Grid.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Framework\Model\Exception as CoreException;
+
+class Grid extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Payments ajax grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_view->loadLayout()->renderLayout();
+            return;
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Index.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5204c44b9142d69315ce1e902162bdc303464c4
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+class Index extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Recurring payments list
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Recurring Billing Payments'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_RecurringPayment::recurring_payment');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Orders.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Orders.php
new file mode 100644
index 0000000000000000000000000000000000000000..035973e2afb6e84085fd6b3f82c2e61948b17d40
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/Orders.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Framework\App\Action\NotFoundException;
+
+class Orders extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Payment orders ajax grid
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        try {
+            $this->_initPayment();
+            $this->_view->loadLayout()->renderLayout();
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+            throw new NotFoundException();
+        }
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdatePayment.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdatePayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..62bb5ed1efc6860db6e36dcaf256414ba4a8416a
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdatePayment.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Framework\Model\Exception as CoreException;
+
+class UpdatePayment extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Payment information updater action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $payment = null;
+        try {
+            $payment = $this->_initPayment();
+            $payment->fetchUpdate();
+            if ($payment->hasDataChanges()) {
+                $payment->save();
+                $this->messageManager->addSuccess(__('You updated the payment.'));
+            } else {
+                $this->messageManager->addNotice(__('The payment has no changes.'));
+            }
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We could not update the payment.'));
+            $this->_logger->logException($e);
+        }
+        if ($payment) {
+            $this->_redirect('sales/*/view', array(self::PARAM_PAYMENT => $payment->getId()));
+        } else {
+            $this->_redirect('sales/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdateState.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdateState.php
new file mode 100644
index 0000000000000000000000000000000000000000..219f8544353b1e3813a847b7eae850c0032c7b99
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/UpdateState.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Framework\Model\Exception as CoreException;
+
+class UpdateState extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * Payment state updater action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $payment = null;
+        try {
+            $payment = $this->_initPayment();
+            $action = $this->getRequest()->getParam(self::PARAM_ACTION);
+
+            switch ($action) {
+                case self::ACTION_CANCEL:
+                    $payment->cancel();
+                    break;
+                case self::ACTION_SUSPEND:
+                    $payment->suspend();
+                    break;
+                case self::ACTION_ACTIVATE:
+                    $payment->activate();
+                    break;
+                default:
+                    throw new \Exception(sprintf('Wrong action parameter: %s', $action));
+            }
+            $this->messageManager->addSuccess(__('The payment state has been updated.'));
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We could not update the payment.'));
+            $this->_logger->logException($e);
+        }
+        if ($payment) {
+            $this->_redirect('sales/*/view', array(self::PARAM_PAYMENT => $payment->getId()));
+        } else {
+            $this->_redirect('sales/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/View.php b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce2eb20f88052174e76e40ba47000dbf1965deae
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/Adminhtml/RecurringPayment/View.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment;
+
+use \Magento\Framework\Model\Exception as CoreException;
+
+class View extends \Magento\RecurringPayment\Controller\Adminhtml\RecurringPayment
+{
+    /**
+     * View recurring payment details
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_title->add(__('Recurring Billing Payments'));
+            $payment = $this->_initPayment();
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_RecurringPayment::recurring_payment');
+            $this->_title->add(__('Payment #%1', $payment->getReferenceId()));
+            $this->_view->renderLayout();
+            return;
+        } catch (CoreException $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/Download.php b/app/code/Magento/RecurringPayment/Controller/Download/DownloadPaymentCustomOption.php
similarity index 95%
rename from app/code/Magento/RecurringPayment/Controller/Download.php
rename to app/code/Magento/RecurringPayment/Controller/Download/DownloadPaymentCustomOption.php
index 0c5dfd96fa9bd0caa785851fb2045f598daf1944..2d32b1df0e5e2c8c89d04639e2e0b2ed7e6a46a4 100644
--- a/app/code/Magento/RecurringPayment/Controller/Download.php
+++ b/app/code/Magento/RecurringPayment/Controller/Download/DownloadPaymentCustomOption.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\RecurringPayment\Controller;
+namespace Magento\RecurringPayment\Controller\Download;
 
-class Download extends \Magento\Framework\App\Action\Action
+class DownloadPaymentCustomOption extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Sales\Model\Download
@@ -40,35 +41,6 @@ class Download extends \Magento\Framework\App\Action\Action
         $this->download = $download;
     }
 
-    /**
-     * Payment custom options download action
-     *
-     * @return void
-     */
-    public function downloadPaymentCustomOptionAction()
-    {
-        $recurringPayment = $this->_objectManager->create(
-            'Magento\RecurringPayment\Model\Payment'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!$recurringPayment->getId()) {
-            $this->_forward('noroute');
-        }
-
-        $orderItemInfo = $recurringPayment->getData('order_item_info');
-        try {
-            $buyRequest = unserialize($orderItemInfo['info_buyRequest']);
-            if ($buyRequest['product'] != $orderItemInfo['product_id']) {
-                throw new \Exception();
-            }
-            $this->download->downloadFile($this->getOptionInfo($buyRequest));
-        } catch (\Exception $e) {
-            $this->_forward('noroute');
-        }
-    }
-
     /**
      * Retrieve custom option information
      *
@@ -97,4 +69,33 @@ class Download extends \Magento\Framework\App\Action\Action
         }
         return $info;
     }
+
+    /**
+     * Payment custom options download action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $recurringPayment = $this->_objectManager->create(
+            'Magento\RecurringPayment\Model\Payment'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!$recurringPayment->getId()) {
+            $this->_forward('noroute');
+        }
+
+        $orderItemInfo = $recurringPayment->getData('order_item_info');
+        try {
+            $buyRequest = unserialize($orderItemInfo['info_buyRequest']);
+            if ($buyRequest['product'] != $orderItemInfo['product_id']) {
+                throw new \Exception();
+            }
+            $this->download->downloadFile($this->getOptionInfo($buyRequest));
+        } catch (\Exception $e) {
+            $this->_forward('noroute');
+        }
+    }
 }
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
index 7e967b762444059e60d338b48b1b523b5ccccf9f..f6e988b9c9a2e2bf824cb0375e77aae48dfb1312 100644
--- a/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment.php
@@ -90,107 +90,6 @@ class RecurringPayment extends \Magento\Framework\App\Action\Action
         return parent::dispatch($request);
     }
 
-    /**
-     * Payments listing
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Recurring Billing Payments'));
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Payment main view
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Payment related orders view
-     *
-     * @return void
-     */
-    public function ordersAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Attempt to set payment state
-     *
-     * @return void
-     */
-    public function updateStateAction()
-    {
-        $payment = null;
-        try {
-            $payment = $this->_initPayment();
-
-            switch ($this->getRequest()->getParam('action')) {
-                case 'cancel':
-                    $payment->cancel();
-                    break;
-                case 'suspend':
-                    $payment->suspend();
-                    break;
-                case 'activate':
-                    $payment->activate();
-                    break;
-                default:
-                    break;
-            }
-            $this->messageManager->addSuccess(__('The payment state has been updated.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We couldn\'t update the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        if ($payment) {
-            $this->_redirect('*/*/view', array('payment' => $payment->getId()));
-        } else {
-            $this->_redirect('*/*/');
-        }
-    }
-
-    /**
-     * Fetch an update with payment
-     *
-     * @return void
-     */
-    public function updatePaymentAction()
-    {
-        $payment = null;
-        try {
-            $payment = $this->_initPayment();
-            $payment->fetchUpdate();
-            if ($payment->hasDataChanges()) {
-                $payment->save();
-                $this->messageManager->addSuccess(__('The payment has been updated.'));
-            } else {
-                $this->messageManager->addNotice(__('The payment has no changes.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We couldn\'t update the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        if ($payment) {
-            $this->_redirect('*/*/view', array('payment' => $payment->getId()));
-        } else {
-            $this->_redirect('*/*/');
-        }
-    }
-
     /**
      * Generic payment view action
      *
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Index.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f9b167b2b9983c0b56ff7c1961a82561a92c57f
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\RecurringPayment;
+
+class Index extends \Magento\RecurringPayment\Controller\RecurringPayment
+{
+    /**
+     * Payments listing
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Recurring Billing Payments'));
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Orders.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Orders.php
new file mode 100644
index 0000000000000000000000000000000000000000..d6f6f93e032bdf45364fb7d243957aea306e949f
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/Orders.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\RecurringPayment;
+
+class Orders extends \Magento\RecurringPayment\Controller\RecurringPayment
+{
+    /**
+     * Payment related orders view
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_viewAction();
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdatePayment.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdatePayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..b59c6a1f6c7a54dc481ba5843af327ffdd09c658
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdatePayment.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\RecurringPayment;
+
+class UpdatePayment extends \Magento\RecurringPayment\Controller\RecurringPayment
+{
+    /**
+     * Fetch an update with payment
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $payment = null;
+        try {
+            $payment = $this->_initPayment();
+            $payment->fetchUpdate();
+            if ($payment->hasDataChanges()) {
+                $payment->save();
+                $this->messageManager->addSuccess(__('The payment has been updated.'));
+            } else {
+                $this->messageManager->addNotice(__('The payment has no changes.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We couldn\'t update the payment.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        if ($payment) {
+            $this->_redirect('*/*/view', array('payment' => $payment->getId()));
+        } else {
+            $this->_redirect('*/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdateState.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdateState.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1882d1e2fe108f00226d9942a0ff7e7eabb523c
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/UpdateState.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\RecurringPayment;
+
+class UpdateState extends \Magento\RecurringPayment\Controller\RecurringPayment
+{
+    /**
+     * Attempt to set payment state
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $payment = null;
+        try {
+            $payment = $this->_initPayment();
+
+            switch ($this->getRequest()->getParam('action')) {
+                case 'cancel':
+                    $payment->cancel();
+                    break;
+                case 'suspend':
+                    $payment->suspend();
+                    break;
+                case 'activate':
+                    $payment->activate();
+                    break;
+                default:
+                    break;
+            }
+            $this->messageManager->addSuccess(__('The payment state has been updated.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We couldn\'t update the payment.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        if ($payment) {
+            $this->_redirect('*/*/view', array('payment' => $payment->getId()));
+        } else {
+            $this->_redirect('*/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/RecurringPayment/Controller/RecurringPayment/View.php b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..48ad1a6ea50e81084fef23efe5a6589b26521c42
--- /dev/null
+++ b/app/code/Magento/RecurringPayment/Controller/RecurringPayment/View.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\RecurringPayment\Controller\RecurringPayment;
+
+class View extends \Magento\RecurringPayment\Controller\RecurringPayment
+{
+    /**
+     * Payment main view
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_viewAction();
+    }
+}
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Customer/Accounts.php b/app/code/Magento/Reports/Block/Adminhtml/Customer/Accounts.php
index 4104546d1b3bd729b026a75c98026acf63e4aef4..38b8f579c2e3246165680d0b54e3590d2767b873 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Customer/Accounts.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Customer/Accounts.php
@@ -44,6 +44,6 @@ class Accounts extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_customer_accounts';
         $this->_headerText = __('New Accounts');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Customer/Orders.php b/app/code/Magento/Reports/Block/Adminhtml/Customer/Orders.php
index 8cb680431c8dfdbbf3110af69a9c595943e2136b..56e81890d3cf42b772d84c8fbb304cf0ca2b921d 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Customer/Orders.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Customer/Orders.php
@@ -46,6 +46,6 @@ class Orders extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_customer_orders';
         $this->_headerText = __('Customers by number of orders');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Customer/Totals.php b/app/code/Magento/Reports/Block/Adminhtml/Customer/Totals.php
index ce2778f19f7f3a3621b8afcf163584dcacbe39fa..3d6aa32353b39c661f33a7518fe1059d26ca9885 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Customer/Totals.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Customer/Totals.php
@@ -44,6 +44,6 @@ class Totals extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_customer_totals';
         $this->_headerText = __('Customers by Orders Total');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Product.php b/app/code/Magento/Reports/Block/Adminhtml/Product.php
index 822076d817fa64dc21e49c4f724f3f7b195e1c4c..0f3968ccf819db75dc4c25bc39653fa2dffa4307 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Product.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Product.php
@@ -39,6 +39,6 @@ class Product extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_product';
         $this->_headerText = __('Products Report');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Product/Downloads.php b/app/code/Magento/Reports/Block/Adminhtml/Product/Downloads.php
index dd9e379880699b6c8bb835e802236f15a305a089..7d2cfcf03360305ee0b9db5196e3bf42939f7d93 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Product/Downloads.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Product/Downloads.php
@@ -39,6 +39,6 @@ class Downloads extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_product_downloads';
         $this->_headerText = __('Downloads');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Product/Lowstock.php b/app/code/Magento/Reports/Block/Adminhtml/Product/Lowstock.php
index ecffb9d8ce981947693c91d2573210ab824fd337..0fb032978afcbe48c7af66141331ec4596a61302 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Product/Lowstock.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Product/Lowstock.php
@@ -39,6 +39,6 @@ class Lowstock extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_product_lowstock';
         $this->_headerText = __('Low stock');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Product/Sold.php b/app/code/Magento/Reports/Block/Adminhtml/Product/Sold.php
index a6612fe773090c2de1c517a30a21a2f40bc250da..5b568ed7c363551771870b6373397aa68ddee7ec 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Product/Sold.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Product/Sold.php
@@ -46,6 +46,6 @@ class Sold extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_product_sold';
         $this->_headerText = __('Products Ordered');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Product/Viewed.php b/app/code/Magento/Reports/Block/Adminhtml/Product/Viewed.php
index 619ff4bd1ca69e6b7e555cff36dff738e49df9f2..b1186d7f357cfb0c81ffbf1b83b4f1931b0460a9 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Product/Viewed.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Product/Viewed.php
@@ -45,7 +45,7 @@ class Viewed extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Most Viewed');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Refresh/Statistics.php b/app/code/Magento/Reports/Block/Adminhtml/Refresh/Statistics.php
index e06ff65716d65a4033a9df047331183f39f5d32f..108f56c12d3edf84226d6b5f3f66ac58c5b102d9 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Refresh/Statistics.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Refresh/Statistics.php
@@ -41,6 +41,6 @@ class Statistics extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_refresh_statistics';
         $this->_headerText = __('Refresh Statistics');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Review/Customer.php b/app/code/Magento/Reports/Block/Adminhtml/Review/Customer.php
index 0ba15890d34e6120ac941df54995d077c0e34487..1961bacfba40820912d40ff1245a3ab7025b0b5b 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Review/Customer.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Review/Customer.php
@@ -39,6 +39,6 @@ class Customer extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_review_customer';
         $this->_headerText = __('Customers Reviews');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Review/Detail.php b/app/code/Magento/Reports/Block/Adminhtml/Review/Detail.php
index f3bb95b9d6a9b5390b416399f3f29e48b7a4a151..0d46d09fa22133246e27f835035e2877760e284f 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Review/Detail.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Review/Detail.php
@@ -36,12 +36,12 @@ class Detail extends \Magento\Backend\Block\Widget\Grid\Container
     protected $_productFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         array $data = array()
     ) {
@@ -61,7 +61,7 @@ class Detail extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Reviews for %1', $product->getName());
 
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->setBackUrl($this->getUrl('reports/report_review/product/'));
         $this->_addBackButton();
     }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Review/Product.php b/app/code/Magento/Reports/Block/Adminhtml/Review/Product.php
index 4074135c68da6623c0b81e45cb5872caade03fb0..08f5982510cdb879d7a3bc6afe852276204b8ce1 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Review/Product.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Review/Product.php
@@ -39,6 +39,6 @@ class Product extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_review_product';
         $this->_headerText = __('Products Reviews');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Bestsellers.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Bestsellers.php
index ffe1f9f3f9b90552ab219be0b27bd439107b91a5..55a21062f30bfebbf7f35f7663585aac84a525c2 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Bestsellers.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Bestsellers.php
@@ -45,7 +45,7 @@ class Bestsellers extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Products Bestsellers Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Coupons.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Coupons.php
index d0f22e09fae5d596340ddbef104be51a866fedc4..3d4a355f86f002c841d2ad9901cc95107dff10f5 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Coupons.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Coupons.php
@@ -45,7 +45,7 @@ class Coupons extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Coupons Usage Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Invoiced.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Invoiced.php
index f4153b53769c1dd0bc7a461361807845022d18dc..e1dfd1d2089619eaaadad1d68d797bffbd5740b5 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Invoiced.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Invoiced.php
@@ -45,7 +45,7 @@ class Invoiced extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Total Invoiced vs. Paid Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Refunded.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Refunded.php
index c919dea6960fe50d3a3c210affcf32f7473bc5e0..2c88133794b94d233d6638558ce9a259b78eb310 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Refunded.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Refunded.php
@@ -45,7 +45,7 @@ class Refunded extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Total Refunded Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales.php
index fd792ea22f6d6e5ffda4ed1bbad8519464bf69df..e4e20ee82327528ec93b894c537f1cde43d7228a 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Sales.php
@@ -45,7 +45,7 @@ class Sales extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Total Ordered Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Shipping.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Shipping.php
index 1c092841a7a587e51c51ccd60cb16289d62e8968..464261a8d06308beaf8cbf2230a2f25e2d076790 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Shipping.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Shipping.php
@@ -45,7 +45,7 @@ class Shipping extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Total Shipped Report');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax.php b/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax.php
index 634d54a447a19a5fad02d7f003d177e3b0df73cd..9a5eabd050950c4a4bef9cd72756aaba1c04eeea 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Sales/Tax.php
@@ -45,7 +45,7 @@ class Tax extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_headerText = __('Order Taxes Report Grouped by Tax Rate');
         parent::_construct();
 
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
         $this->addButton(
             'filter_form_submit',
             array('label' => __('Show Report'), 'onclick' => 'filterFormSubmit()', 'class' => 'primary')
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Search.php b/app/code/Magento/Reports/Block/Adminhtml/Search.php
index 9acebce22380b0f7ce7be6b0456631413b092cc2..34d7f7c8d6ae0b66877ea91df778ef3729dd14ed 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Search.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Search.php
@@ -41,6 +41,6 @@ class Search extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_search';
         $this->_headerText = __('Search Terms');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned.php b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned.php
index 69027c9ffbafe95195fb0dd71c82c23ed19fb4d4..5b094fde55b7a59b5c557e152637a6e5c77a462e 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Abandoned.php
@@ -39,6 +39,6 @@ class Abandoned extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_shopcart_abandoned';
         $this->_headerText = __('Abandoned carts');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Customer.php b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Customer.php
index 451d28b047a1927218bca6172aa071a5a4dfc138..6cd95d3ee81152266d9445ecd76a5786328a2e88 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Customer.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Customer.php
@@ -39,6 +39,6 @@ class Customer extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_shopcart_customer';
         $this->_headerText = __('Customers');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product.php b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product.php
index 7070f0be9bf43bda502cabb17f7874c2365868e3..a16f7dc82d64db1e9a8057e741d53acd6c31f38a 100644
--- a/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product.php
+++ b/app/code/Magento/Reports/Block/Adminhtml/Shopcart/Product.php
@@ -39,6 +39,6 @@ class Product extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_shopcart_product';
         $this->_headerText = __('Products in carts');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Index.php b/app/code/Magento/Reports/Controller/Adminhtml/Index.php
index b954a55e361495b5132003afd6fae51616d5339d..1f388b574cccb1158b0b95c2e9d645f8cf9e9c87 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Index.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Index.php
@@ -29,8 +29,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml;
 
-use Magento\Framework\App\ResponseInterface;
-
 class Index extends \Magento\Backend\App\Action
 {
     /**
@@ -50,62 +48,6 @@ class Index extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Add reports to breadcrumb
-     *
-     * @return $this
-     */
-    public function _initAction()
-    {
-        $this->_view->loadLayout();
-        $this->_addBreadcrumb(__('Reports'), __('Reports'));
-        return $this;
-    }
-
-    /**
-     * Search terms report action
-     *
-     * @return void
-     */
-    public function searchAction()
-    {
-        $this->_title->add(__('Search Terms Report'));
-
-        $this->_eventManager->dispatch('on_view_report', array('report' => 'search'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_search'
-        )->_addBreadcrumb(
-            __('Search Terms'),
-            __('Search Terms')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export search report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportSearchCsvAction()
-    {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.report.search.grid', 'grid.export');
-        return $this->_fileFactory->create('search.csv', $content->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export search report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportSearchExcelAction()
-    {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.report.search.grid', 'grid.export');
-        return $this->_fileFactory->create('search.xml', $content->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..5fd4c864669e7585a98b518c000d1526f258c107
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchCsv.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Index;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportSearchCsv extends \Magento\Reports\Controller\Adminhtml\Index
+{
+    /**
+     * Export search report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.report.search.grid', 'grid.export');
+        return $this->_fileFactory->create('search.csv', $content->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..abf2cf1b9a54f01abfa67d2e6eee4f1a51972af6
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Index/ExportSearchExcel.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Index;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportSearchExcel extends \Magento\Reports\Controller\Adminhtml\Index
+{
+    /**
+     * Export search report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.report.search.grid', 'grid.export');
+        return $this->_fileFactory->create('search.xml', $content->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Index/Search.php b/app/code/Magento/Reports/Controller/Adminhtml/Index/Search.php
new file mode 100644
index 0000000000000000000000000000000000000000..05110501bfdcf75f6b0cd68606f0401c4a7a9231
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Index/Search.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Index;
+
+class Search extends \Magento\Reports\Controller\Adminhtml\Index
+{
+    /**
+     * Add reports to breadcrumb
+     *
+     * @return $this
+     */
+    public function _initAction()
+    {
+        $this->_view->loadLayout();
+        $this->_addBreadcrumb(__('Reports'), __('Reports'));
+        return $this;
+    }
+
+    /**
+     * Search terms report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Search Terms Report'));
+
+        $this->_eventManager->dispatch('on_view_report', array('report' => 'search'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_search'
+        )->_addBreadcrumb(
+            __('Search Terms'),
+            __('Search Terms')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
index 9c9097abcb26d1484425571c141e4cffef969574..03f55337cf0b9bd51341a05794ee6b1ccc592545 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/AbstractReport.php
@@ -22,7 +22,6 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
 /**
  * Admin abstract reports controller
  *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer.php
index 78d701631097a2d891c88af840fa1197e2a0de39..3bda2f3d0dd04b69228fb074bdedb18b67eef4da 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer.php
@@ -30,9 +30,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml\Report;
 
-use Magento\Framework\App\ResponseInterface;
-use Magento\Backend\Block\Widget\Grid\ExportInterface;
-
 class Customer extends \Magento\Backend\App\Action
 {
     /**
@@ -70,168 +67,6 @@ class Customer extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * New accounts action
-     *
-     * @return void
-     */
-    public function accountsAction()
-    {
-        $this->_title->add(__('New Accounts Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_customers_accounts'
-        )->_addBreadcrumb(
-            __('New Accounts'),
-            __('New Accounts')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export new accounts report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportAccountsCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'new_accounts.csv';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export new accounts report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportAccountsExcelAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'new_accounts.xml';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Customers by number of orders action
-     *
-     * @return void
-     */
-    public function ordersAction()
-    {
-        $this->_title->add(__('Order Count Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_customers_orders'
-        )->_addBreadcrumb(
-            __('Customers by Number of Orders'),
-            __('Customers by Number of Orders')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export customers most ordered report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportOrdersCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'customers_orders.csv';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export customers most ordered report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportOrdersExcelAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'customers_orders.xml';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Customers by orders total action
-     *
-     * @return void
-     */
-    public function totalsAction()
-    {
-        $this->_title->add(__('Order Total Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_customers_totals'
-        )->_addBreadcrumb(
-            __('Customers by Orders Total'),
-            __('Customers by Orders Total')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export customers biggest totals report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportTotalsCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'customer_totals.csv';
-        /** @var ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export customers biggest totals report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportTotalsExcelAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'customer_totals.xml';
-        /** @var ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php
new file mode 100644
index 0000000000000000000000000000000000000000..e14d815392da74109b0be1beff58527ed735cff7
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Accounts.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+class Accounts extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * New accounts action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('New Accounts Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_customers_accounts'
+        )->_addBreadcrumb(
+            __('New Accounts'),
+            __('New Accounts')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..e42698872c9564752da427abaaf91e17af911512
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsCsv.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportAccountsCsv extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export new accounts report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'new_accounts.csv';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..daf72b3ebf9013039468ea4be8391da534ff47e5
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportAccountsExcel.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportAccountsExcel extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export new accounts report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'new_accounts.xml';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6e31473540fc804fd0b70b41b59d2d08fc88804
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersCsv.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportOrdersCsv extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export customers most ordered report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'customers_orders.csv';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..d8d083a1f78713bd8a2020e4aedfbf7e55cc0a58
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportOrdersExcel.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportOrdersExcel extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export customers most ordered report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'customers_orders.xml';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..11674d03e74612719586bb5806b6bacf4cff2c3d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsCsv.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportTotalsCsv extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export customers biggest totals report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'customer_totals.csv';
+        /** @var ExportInterface $exportBlock  */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..dcc59b3f24c45c51625deec4effe1d42b08a3eaa
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/ExportTotalsExcel.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportTotalsExcel extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Export customers biggest totals report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'customer_totals.xml';
+        /** @var ExportInterface $exportBlock  */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab4742e7642d63f00182033c2f322a1cf932f7b8
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Orders.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+class Orders extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Customers by number of orders action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Order Count Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_customers_orders'
+        )->_addBreadcrumb(
+            __('Customers by Number of Orders'),
+            __('Customers by Number of Orders')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php
new file mode 100644
index 0000000000000000000000000000000000000000..7527d624c5a9f9a0e935786a6db9fec2703b6463
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Customer/Totals.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Customer;
+
+class Totals extends \Magento\Reports\Controller\Adminhtml\Report\Customer
+{
+    /**
+     * Customers by orders total action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Order Total Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_customers_totals'
+        )->_addBreadcrumb(
+            __('Customers by Orders Total'),
+            __('Customers by Orders Total')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product.php
index 9074c991e4223b46ac249563de57e09435e81fd9..2db085f98f85dbf98bae1f8261897f3e2a10a5e2 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product.php
@@ -22,7 +22,6 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-
 /**
  * Product reports admin controller
  *
@@ -30,10 +29,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml\Report;
 
-use Magento\Framework\App\ResponseInterface;
-use Magento\Backend\Block\Widget\Grid\ExportInterface;
-use Magento\Reports\Model\Flag;
-
 class Product extends AbstractReport
 {
     /**
@@ -47,250 +42,4 @@ class Product extends AbstractReport
         $this->_addBreadcrumb(__('Products'), __('Products'));
         return $this;
     }
-
-    /**
-     * Sold Products Report Action
-     *
-     * @return void
-     */
-    public function soldAction()
-    {
-        $this->_title->add(__('Ordered Products Report'));
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_products_sold'
-        )->_addBreadcrumb(
-            __('Products Ordered'),
-            __('Products Ordered')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export Sold Products report to CSV format action
-     *
-     * @return ResponseInterface
-     */
-    public function exportSoldCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'products_ordered.csv';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export Sold Products report to XML format action
-     *
-     * @return ResponseInterface
-     */
-    public function exportSoldExcelAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'products_ordered.xml';
-        /** @var ExportInterface $exportBlock */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Most viewed products
-     *
-     * @return void
-     */
-    public function viewedAction()
-    {
-        $this->_title->add(__('Product Views Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_PRODUCT_VIEWED_FLAG_CODE, 'viewed');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_products_viewed'
-        )->_addBreadcrumb(
-            __('Products Most Viewed Report'),
-            __('Products Most Viewed Report')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_product_viewed.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export products most viewed report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportViewedCsvAction()
-    {
-        $fileName = 'products_mostviewed.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Viewed\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export products most viewed report to XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportViewedExcelAction()
-    {
-        $fileName = 'products_mostviewed.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Viewed\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create(
-            $fileName,
-            $grid->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Low stock action
-     *
-     * @return void
-     */
-    public function lowstockAction()
-    {
-        $this->_title->add(__('Low Stock Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_products_lowstock'
-        )->_addBreadcrumb(
-            __('Low Stock'),
-            __('Low Stock')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export low stock products report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportLowstockCsvAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'products_lowstock.csv';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.product.lowstock.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Export low stock products report to XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportLowstockExcelAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'products_lowstock.xml';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.product.lowstock.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Downloads action
-     *
-     * @return void
-     */
-    public function downloadsAction()
-    {
-        $this->_title->add(__('Downloads Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Downloadable::report_products_downloads'
-        )->_addBreadcrumb(
-            __('Downloads'),
-            __('Downloads')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Downloads')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export products downloads report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportDownloadsCsvAction()
-    {
-        $fileName = 'products_downloads.csv';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Product\Downloads\Grid'
-        )->setSaveParametersInSession(
-            true
-        )->getCsv();
-
-        return $this->_fileFactory->create($fileName, $content);
-    }
-
-    /**
-     * Export products downloads report to XLS format
-     *
-     * @return ResponseInterface
-     */
-    public function exportDownloadsExcelAction()
-    {
-        $fileName = 'products_downloads.xml';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Product\Downloads\Grid'
-        )->setSaveParametersInSession(
-            true
-        )->getExcel(
-            $fileName
-        );
-
-        return $this->_fileFactory->create($fileName, $content);
-    }
-
-    /**
-     * Check is allowed for report
-     *
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        switch ($this->getRequest()->getActionName()) {
-            case 'viewed':
-                return $this->_authorization->isAllowed('Magento_Reports::viewed');
-                break;
-            case 'sold':
-                return $this->_authorization->isAllowed('Magento_Reports::sold');
-                break;
-            case 'lowstock':
-                return $this->_authorization->isAllowed('Magento_Reports::lowstock');
-                break;
-            default:
-                return $this->_authorization->isAllowed('Magento_Reports::report_products');
-                break;
-        }
-    }
 }
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php
new file mode 100644
index 0000000000000000000000000000000000000000..657f560ca4c5bf28009369b29e3fb17b800e0d7b
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Downloads.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+class Downloads extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Downloads action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Downloads Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Downloadable::report_products_downloads'
+        )->_addBreadcrumb(
+            __('Downloads'),
+            __('Downloads')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Downloads')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..fb4b73752010bdc8c25f8dfc3e4e3f9bca524124
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsCsv.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportDownloadsCsv extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export products downloads report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'products_downloads.csv';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Product\Downloads\Grid'
+        )->setSaveParametersInSession(
+            true
+        )->getCsv();
+
+        return $this->_fileFactory->create($fileName, $content);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..174b0d2d8f5d975724097c5ec94c0f97314fb36b
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportDownloadsExcel.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportDownloadsExcel extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export products downloads report to XLS format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'products_downloads.xml';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Product\Downloads\Grid'
+        )->setSaveParametersInSession(
+            true
+        )->getExcel(
+            $fileName
+        );
+
+        return $this->_fileFactory->create($fileName, $content);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..a05b6e7fa341d116a35addd0b000887e320e448a
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockCsv.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportLowstockCsv extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export low stock products report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'products_lowstock.csv';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.product.lowstock.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..63d39bcbaf663ce8e0068820c9d68f3558c2426e
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportLowstockExcel.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportLowstockExcel extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export low stock products report to XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'products_lowstock.xml';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.product.lowstock.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..d272676b9902e8c5770f359242ae8dddfed53664
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldCsv.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportSoldCsv extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export Sold Products report to CSV format action
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'products_ordered.csv';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f65a5e33ca1977bf7743aa6002ea1237db1647d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportSoldExcel.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\Block\Widget\Grid\ExportInterface;
+
+class ExportSoldExcel extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export Sold Products report to XML format action
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'products_ordered.xml';
+        /** @var ExportInterface $exportBlock */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('adminhtml.report.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..005a12ab957ee60e36ad19d4f19a7144c4f6541d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedCsv.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportViewedCsv extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export products most viewed report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'products_mostviewed.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Viewed\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..c397944f0338c23ecf0304b2ee63bb63fb52a1f5
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/ExportViewedExcel.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportViewedExcel extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::report_products');
+    }
+
+    /**
+     * Export products most viewed report to XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'products_mostviewed.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Product\Viewed\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create(
+            $fileName,
+            $grid->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php
new file mode 100644
index 0000000000000000000000000000000000000000..d08905cbcb25b13b7a2a6fb049477f4534cca230
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Lowstock.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+class Lowstock extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::lowstock');
+    }
+
+    /**
+     * Low stock action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Low Stock Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_products_lowstock'
+        )->_addBreadcrumb(
+            __('Low Stock'),
+            __('Low Stock')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php
new file mode 100644
index 0000000000000000000000000000000000000000..b84e3cfc1193e3c35fdc54f3b183188bb06ef87f
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Sold.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+class Sold extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::sold');
+    }
+
+    /**
+     * Sold Products Report Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Ordered Products Report'));
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_products_sold'
+        )->_addBreadcrumb(
+            __('Products Ordered'),
+            __('Products Ordered')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
new file mode 100644
index 0000000000000000000000000000000000000000..b2e85c8631efb1dee739a8da5f59c013058cdb3c
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Product/Viewed.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Product;
+
+use \Magento\Reports\Model\Flag;
+
+class Viewed extends \Magento\Reports\Controller\Adminhtml\Report\Product
+{
+    /**
+     * Check is allowed for report
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Reports::viewed');
+    }
+
+    /**
+     * Most viewed products
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Product Views Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_PRODUCT_VIEWED_FLAG_CODE, 'viewed');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_products_viewed'
+        )->_addBreadcrumb(
+            __('Products Most Viewed Report'),
+            __('Products Most Viewed Report')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_product_viewed.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review.php
index a59fbdd3358671a4ed3dfbe4645af25c4743bc08..8b1f8773fa48f397b7896a1ad562262fc6ee3f24 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review.php
@@ -29,8 +29,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml\Report;
 
-use Magento\Framework\App\ResponseInterface;
-
 class Review extends \Magento\Backend\App\Action
 {
     /**
@@ -63,161 +61,6 @@ class Review extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Customer Reviews Report action
-     *
-     * @return void
-     */
-    public function customerAction()
-    {
-        $this->_title->add(__('Customer Reviews Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Review::report_review_customer'
-        )->_addBreadcrumb(
-            __('Customers Report'),
-            __('Customers Report')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export review customer report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCustomerCsvAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'review_customer.csv';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.review.customer.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export review customer report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCustomerExcelAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'review_customer.xml';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.review.customer.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create($fileName, $exportBlock->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Product reviews report action
-     *
-     * @return void
-     */
-    public function productAction()
-    {
-        $this->_title->add(__('Product Reviews Report'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Review::report_review_product'
-        )->_addBreadcrumb(
-            __('Products Report'),
-            __('Products Report')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export review product report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductCsvAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'review_product.csv';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.review.product.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export review product report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductExcelAction()
-    {
-        $this->_view->loadLayout(false);
-        $fileName = 'review_product.xml';
-        $exportBlock = $this->_view->getLayout()->getChildBlock(
-            'adminhtml.block.report.review.product.grid',
-            'grid.export'
-        );
-        return $this->_fileFactory->create($fileName, $exportBlock->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Details action
-     *
-     * @return void
-     */
-    public function productDetailAction()
-    {
-        $this->_title->add(__('Details'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Review::report_review'
-        )->_addBreadcrumb(
-            __('Products Report'),
-            __('Products Report')
-        )->_addBreadcrumb(
-            __('Product Reviews'),
-            __('Product Reviews')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Review\Detail')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export review product detail report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductDetailCsvAction()
-    {
-        $fileName = 'review_product_detail.csv';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Review\Detail\Grid'
-        )->getCsv();
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export review product detail report to ExcelXML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductDetailExcelAction()
-    {
-        $fileName = 'review_product_detail.xml';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Review\Detail\Grid'
-        )->getExcel(
-            $fileName
-        );
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php
new file mode 100644
index 0000000000000000000000000000000000000000..e338f21102737e4b38d404a7b954d892c9e1ee71
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Customer.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+class Customer extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Customer Reviews Report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Reviews Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Review::report_review_customer'
+        )->_addBreadcrumb(
+            __('Customers Report'),
+            __('Customers Report')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..19da1836eeee2206cf3a85519d1e21e739129501
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerCsv.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCustomerCsv extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review customer report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'review_customer.csv';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.review.customer.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..f6abf2458b2c8a0519f5656f242211e2de1dae0a
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportCustomerExcel.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCustomerExcel extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review customer report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'review_customer.xml';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.review.customer.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create($fileName, $exportBlock->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..0349563635da1a334a7893c548b86563fa22de60
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductCsv.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductCsv extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review product report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'review_product.csv';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.review.product.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..036316d46fee802790eebe4289f9457df28531f9
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailCsv.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductDetailCsv extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review product detail report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'review_product_detail.csv';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Review\Detail\Grid'
+        )->getCsv();
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..9776446793ec7529e24400e8c4bdeb8d6c232768
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductDetailExcel.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductDetailExcel extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review product detail report to ExcelXML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'review_product_detail.xml';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Review\Detail\Grid'
+        )->getExcel(
+            $fileName
+        );
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b586573591b1de32b6766569215e313d3245ae4
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ExportProductExcel.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductExcel extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Export review product report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'review_product.xml';
+        $exportBlock = $this->_view->getLayout()->getChildBlock(
+            'adminhtml.block.report.review.product.grid',
+            'grid.export'
+        );
+        return $this->_fileFactory->create($fileName, $exportBlock->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b08b7fea8bfe9cfd9251fccf98fade87548d17b
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/Product.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+class Product extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Product reviews report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Product Reviews Report'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Review::report_review_product'
+        )->_addBreadcrumb(
+            __('Products Report'),
+            __('Products Report')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ProductDetail.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ProductDetail.php
new file mode 100644
index 0000000000000000000000000000000000000000..86395a2e1b032a7aa7b9b8b270139d67f0717133
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Review/ProductDetail.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Review;
+
+class ProductDetail extends \Magento\Reports\Controller\Adminhtml\Report\Review
+{
+    /**
+     * Details action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Details'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Review::report_review'
+        )->_addBreadcrumb(
+            __('Products Report'),
+            __('Products Report')
+        )->_addBreadcrumb(
+            __('Product Reviews'),
+            __('Product Reviews')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Review\Detail')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales.php
index 17bdbb060526573b0ee596ce0f12b3ef543d277f..77c99ca813d4eb784b88adb93d405669c03123a1 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales.php
@@ -29,9 +29,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml\Report;
 
-use Magento\Framework\App\ResponseInterface;
-use Magento\Reports\Model\Flag;
-
 class Sales extends AbstractReport
 {
     /**
@@ -46,401 +43,6 @@ class Sales extends AbstractReport
         return $this;
     }
 
-    /**
-     * Sales report action
-     *
-     * @return void
-     */
-    public function salesAction()
-    {
-        $this->_title->add(__('Sales Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_ORDER_FLAG_CODE, 'sales');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_sales'
-        )->_addBreadcrumb(
-            __('Sales Report'),
-            __('Sales Report')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_sales.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Best sellers report action
-     *
-     * @return void
-     */
-    public function bestsellersAction()
-    {
-        $this->_title->add(__('Best Sellers Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_BESTSELLERS_FLAG_CODE, 'bestsellers');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_products_bestsellers'
-        )->_addBreadcrumb(
-            __('Products Bestsellers Report'),
-            __('Products Bestsellers Report')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_bestsellers.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export bestsellers report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportBestsellersCsvAction()
-    {
-        $fileName = 'bestsellers.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Bestsellers\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export bestsellers report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportBestsellersExcelAction()
-    {
-        $fileName = 'bestsellers.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Bestsellers\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Refresh statistics for last 25 hours
-     *
-     * @return void
-     */
-    public function refreshRecentAction()
-    {
-        $this->_forward('refreshRecent', 'report_statistics');
-    }
-
-    /**
-     * Refresh statistics for all period
-     *
-     * @return void
-     */
-    public function refreshLifetimeAction()
-    {
-        $this->_forward('refreshLifetime', 'report_statistics');
-    }
-
-    /**
-     * Export sales report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportSalesCsvAction()
-    {
-        $fileName = 'sales.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Sales\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export sales report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportSalesExcelAction()
-    {
-        $fileName = 'sales.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Sales\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Tax report action
-     *
-     * @return void
-     */
-    public function taxAction()
-    {
-        $this->_title->add(__('Tax Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_TAX_FLAG_CODE, 'tax');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_tax'
-        )->_addBreadcrumb(
-            __('Tax'),
-            __('Tax')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_tax.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export tax report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportTaxCsvAction()
-    {
-        $fileName = 'tax.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Tax\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export tax report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportTaxExcelAction()
-    {
-        $fileName = 'tax.xml';
-        /** @var \Magento\Reports\Block\Adminhtml\Sales\Tax\Grid $grid */
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Tax\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Shipping report action
-     *
-     * @return void
-     */
-    public function shippingAction()
-    {
-        $this->_title->add(__('Shipping Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_SHIPPING_FLAG_CODE, 'shipping');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_shipping'
-        )->_addBreadcrumb(
-            __('Shipping'),
-            __('Shipping')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_shipping.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export shipping report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportShippingCsvAction()
-    {
-        $fileName = 'shipping.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Shipping\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export shipping report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportShippingExcelAction()
-    {
-        $fileName = 'shipping.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Shipping\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Invoice report action
-     *
-     * @return void
-     */
-    public function invoicedAction()
-    {
-        $this->_title->add(__('Invoice Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_INVOICE_FLAG_CODE, 'invoiced');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_invoiced'
-        )->_addBreadcrumb(
-            __('Total Invoiced'),
-            __('Total Invoiced')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_invoiced.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export invoiced report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportInvoicedCsvAction()
-    {
-        $fileName = 'invoiced.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Invoiced\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export invoiced report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportInvoicedExcelAction()
-    {
-        $fileName = 'invoiced.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Invoiced\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Refunds report action
-     *
-     * @return void
-     */
-    public function refundedAction()
-    {
-        $this->_title->add(__('Refunds Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_REFUNDED_FLAG_CODE, 'refunded');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_refunded'
-        )->_addBreadcrumb(
-            __('Total Refunded'),
-            __('Total Refunded')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_refunded.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export refunded report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportRefundedCsvAction()
-    {
-        $fileName = 'refunded.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Refunded\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export refunded report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportRefundedExcelAction()
-    {
-        $fileName = 'refunded.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Refunded\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Coupons report action
-     *
-     * @return void
-     */
-    public function couponsAction()
-    {
-        $this->_title->add(__('Coupons Report'));
-
-        $this->_showLastExecutionTime(Flag::REPORT_COUPONS_FLAG_CODE, 'coupons');
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_salesroot_coupons'
-        )->_addBreadcrumb(
-            __('Coupons'),
-            __('Coupons')
-        );
-
-        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_coupons.grid');
-        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
-
-        $this->_initReportAction(array($gridBlock, $filterFormBlock));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export coupons report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCouponsCsvAction()
-    {
-        $fileName = 'coupons.csv';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Coupons\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export coupons report grid to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCouponsExcelAction()
-    {
-        $fileName = 'coupons.xml';
-        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Coupons\Grid');
-        $this->_initReportAction($grid);
-        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Refresh report statistics action
-     *
-     * @return void
-     */
-    public function refreshStatisticsAction()
-    {
-        $this->_forward('index', 'report_statistics');
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php
new file mode 100644
index 0000000000000000000000000000000000000000..2200f9f6d0140847dfa8ac5ebc0b0cc92931839d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Bestsellers.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Bestsellers extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Best sellers report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Best Sellers Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_BESTSELLERS_FLAG_CODE, 'bestsellers');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_products_bestsellers'
+        )->_addBreadcrumb(
+            __('Products Bestsellers Report'),
+            __('Products Bestsellers Report')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_bestsellers.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php
new file mode 100644
index 0000000000000000000000000000000000000000..a9b40d97ca4b65f01e12591c2feec9afd9f114bb
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Coupons.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Coupons extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Coupons report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Coupons Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_COUPONS_FLAG_CODE, 'coupons');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_coupons'
+        )->_addBreadcrumb(
+            __('Coupons'),
+            __('Coupons')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_coupons.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..1bdf29faffa57cbc912880debecbf70377008c1f
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportBestsellersCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export bestsellers report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'bestsellers.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Bestsellers\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f1043b2debb914e4f7b1153dfaefb758592ec0b
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportBestsellersExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportBestsellersExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export bestsellers report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'bestsellers.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Bestsellers\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..d81476ac913f8a420d80fc4b7b2c5da6bf1e1a9d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCouponsCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export coupons report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'coupons.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Coupons\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e18f05d5ea6e3a10db2dcff36640382769d3efb
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportCouponsExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCouponsExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export coupons report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'coupons.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Coupons\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..083950a4c15928ec7a6cfcbe4d6ff9ff302a1734
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportInvoicedCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export invoiced report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'invoiced.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Invoiced\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..390c9c9b8b047c1c725791ffea2a18603cabaee8
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportInvoicedExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportInvoicedExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export invoiced report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'invoiced.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Invoiced\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..45cabd7b88b4afcf8e5577b0464c347f3a4abe0f
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportRefundedCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export refunded report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'refunded.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Refunded\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..a4c2df9c4b2e315e6942897338ca3e370c56f3f6
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportRefundedExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportRefundedExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export refunded report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'refunded.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Refunded\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..75c1e64f7dd0dccf114e23ad5259cb948c611e29
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportSalesCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export sales report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'sales.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Sales\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d1417a7717af0eb4f58310292b81bcac9354412
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportSalesExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportSalesExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export sales report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'sales.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Sales\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..950d54e8f530e44db45cab755d67b0c0b47b41bb
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportShippingCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export shipping report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shipping.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Shipping\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae09cbb8effd7fae9f2eecc264afc736c267c249
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportShippingExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportShippingExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export shipping report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shipping.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Shipping\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..a03f0ff106691491d9ae20b0f750443c9ed8c96f
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxCsv.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportTaxCsv extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export tax report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'tax.csv';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Tax\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..a68d066a8d7f4523063a20d3e0819eeb416e0874
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/ExportTaxExcel.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportTaxExcel extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Export tax report grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'tax.xml';
+        $grid = $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Sales\Tax\Grid');
+        $this->_initReportAction($grid);
+        return $this->_fileFactory->create($fileName, $grid->getExcelFile($fileName), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php
new file mode 100644
index 0000000000000000000000000000000000000000..d926b342de3ab51d606cce0ec33f7df40e317538
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Invoiced.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Invoiced extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Invoice report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Invoice Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_INVOICE_FLAG_CODE, 'invoiced');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_invoiced'
+        )->_addBreadcrumb(
+            __('Total Invoiced'),
+            __('Total Invoiced')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_invoiced.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshLifetime.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshLifetime.php
new file mode 100644
index 0000000000000000000000000000000000000000..059fa892f32aa09e456f98327879cdc8aa529894
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshLifetime.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+class RefreshLifetime extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Refresh statistics for all period
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('refreshLifetime', 'report_statistics');
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshRecent.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshRecent.php
new file mode 100644
index 0000000000000000000000000000000000000000..30a3a5a399e466a235dc13b284afb5b121eb240b
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshRecent.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Refresh statistics for last 25 hours
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('refreshRecent', 'report_statistics');
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshStatistics.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshStatistics.php
new file mode 100644
index 0000000000000000000000000000000000000000..74f1998bf93b4ad28f599c9cf9a090dcdc4412c8
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/RefreshStatistics.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+class RefreshStatistics extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Refresh report statistics action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('index', 'report_statistics');
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef27be675dfee2aeb2757110a544fa10028076b5
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Refunded.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Refunded extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Refunds report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Refunds Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_REFUNDED_FLAG_CODE, 'refunded');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_refunded'
+        )->_addBreadcrumb(
+            __('Total Refunded'),
+            __('Total Refunded')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_refunded.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b864946eeebf79b0de3d4e46dd3172c9f5f7228
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Sales.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Sales extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Sales report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Sales Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_ORDER_FLAG_CODE, 'sales');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_sales'
+        )->_addBreadcrumb(
+            __('Sales Report'),
+            __('Sales Report')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_sales.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Shipping.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Shipping.php
new file mode 100644
index 0000000000000000000000000000000000000000..496e811cfaf454df9092a81a5d7b3e9d42205a24
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Shipping.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Shipping extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Shipping report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Shipping Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_SHIPPING_FLAG_CODE, 'shipping');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_shipping'
+        )->_addBreadcrumb(
+            __('Shipping'),
+            __('Shipping')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_shipping.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php
new file mode 100644
index 0000000000000000000000000000000000000000..c90d75f18fe548a91f4edfbda8c07e06f290b364
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Sales/Tax.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Sales;
+
+use \Magento\Reports\Model\Flag;
+
+class Tax extends \Magento\Reports\Controller\Adminhtml\Report\Sales
+{
+    /**
+     * Tax report action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Report'));
+
+        $this->_showLastExecutionTime(Flag::REPORT_TAX_FLAG_CODE, 'tax');
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_salesroot_tax'
+        )->_addBreadcrumb(
+            __('Tax'),
+            __('Tax')
+        );
+
+        $gridBlock = $this->_view->getLayout()->getBlock('adminhtml_sales_tax.grid');
+        $filterFormBlock = $this->_view->getLayout()->getBlock('grid.filter.form');
+
+        $this->_initReportAction(array($gridBlock, $filterFormBlock));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart.php
index 633d65d7fa368dd7206ca8b205e6747fab8d45de..87782a8f7438431b07f511d688605b862f41351f 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart.php
@@ -29,8 +29,6 @@
  */
 namespace Magento\Reports\Controller\Adminhtml\Report;
 
-use Magento\Framework\App\ResponseInterface;
-
 class Shopcart extends \Magento\Backend\App\Action
 {
     /**
@@ -63,162 +61,6 @@ class Shopcart extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Customer shopping carts action
-     *
-     * @return void
-     */
-    public function customerAction()
-    {
-        $this->_title->add(__('Customer Shopping Carts'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_shopcart_customer'
-        )->_addBreadcrumb(
-            __('Customers Report'),
-            __('Customers Report')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Customer')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export shopcart customer report to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCustomerCsvAction()
-    {
-        $fileName = 'shopcart_customer.csv';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Customer\Grid'
-        )->getCsvFile();
-
-        return $this->_fileFactory->create($fileName, $content);
-    }
-
-    /**
-     * Export shopcart customer report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCustomerExcelAction()
-    {
-        $fileName = 'shopcart_customer.xml';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Customer\Grid'
-        )->getExcelFile(
-            $fileName
-        );
-
-        return $this->_fileFactory->create($fileName, $content);
-    }
-
-    /**
-     * Products in carts action
-     *
-     * @return void
-     */
-    public function productAction()
-    {
-        $this->_title->add(__('Products in Carts'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_shopcart_product'
-        )->_addBreadcrumb(
-            __('Products Report'),
-            __('Products Report')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Product')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export products report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductCsvAction()
-    {
-        $fileName = 'shopcart_product.csv';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Product\Grid'
-        )->getCsvFile();
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export products report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportProductExcelAction()
-    {
-        $fileName = 'shopcart_product.xml';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Product\Grid'
-        )->getExcelFile(
-            $fileName
-        );
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Abandoned carts action
-     *
-     * @return void
-     */
-    public function abandonedAction()
-    {
-        $this->_title->add(__('Abandoned Carts'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_shopcart_abandoned'
-        )->_addBreadcrumb(
-            __('Abandoned Carts'),
-            __('Abandoned Carts')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Abandoned')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Export abandoned carts report grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportAbandonedCsvAction()
-    {
-        $fileName = 'shopcart_abandoned.csv';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid'
-        )->getCsvFile();
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export abandoned carts report to Excel XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportAbandonedExcelAction()
-    {
-        $fileName = 'shopcart_abandoned.xml';
-        $content = $this->_view->getLayout()->createBlock(
-            'Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid'
-        )->getExcelFile(
-            $fileName
-        );
-
-        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php
new file mode 100644
index 0000000000000000000000000000000000000000..65d4918557060f79f6b7d8a57275008dca7d2d68
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Abandoned.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+class Abandoned extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Abandoned carts action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Abandoned Carts'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_shopcart_abandoned'
+        )->_addBreadcrumb(
+            __('Abandoned Carts'),
+            __('Abandoned Carts')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Abandoned')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Customer.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Customer.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ae9e26d2e5d1bdb39391de24863a78890fcc5ab
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Customer.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+class Customer extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Customer shopping carts action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Shopping Carts'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_shopcart_customer'
+        )->_addBreadcrumb(
+            __('Customers Report'),
+            __('Customers Report')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Customer')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..d3f518bbd7537afb422f26e5345379ea4311ea87
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedCsv.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportAbandonedCsv extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export abandoned carts report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_abandoned.csv';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid'
+        )->getCsvFile();
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..051450cc8c8684aedfbf0a8c97cf059251fee6bb
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportAbandonedExcel.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportAbandonedExcel extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export abandoned carts report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_abandoned.xml';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Abandoned\Grid'
+        )->getExcelFile(
+            $fileName
+        );
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..a9ab3b8764f32f51b0c28a5945d34167a082abac
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerCsv.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCustomerCsv extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export shopcart customer report to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_customer.csv';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Customer\Grid'
+        )->getCsvFile();
+
+        return $this->_fileFactory->create($fileName, $content);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..e7dc26ab1c35b1262cb9fff8f769ef7f83ec6a2d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportCustomerExcel.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCustomerExcel extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export shopcart customer report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_customer.xml';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Customer\Grid'
+        )->getExcelFile(
+            $fileName
+        );
+
+        return $this->_fileFactory->create($fileName, $content);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductCsv.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..761b1e89b6aae81c4ef999b943810abf6e47c359
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductCsv.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductCsv extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export products report grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_product.csv';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Product\Grid'
+        )->getCsvFile();
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductExcel.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..432b5a5588a76dfe26fab3de3162cf1fc16ccc33
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/ExportProductExcel.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportProductExcel extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Export products report to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $fileName = 'shopcart_product.xml';
+        $content = $this->_view->getLayout()->createBlock(
+            'Magento\Reports\Block\Adminhtml\Shopcart\Product\Grid'
+        )->getExcelFile(
+            $fileName
+        );
+
+        return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php
new file mode 100644
index 0000000000000000000000000000000000000000..93869d733a599b0f39ab571a2d739b63c741163d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Shopcart/Product.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Shopcart;
+
+class Product extends \Magento\Reports\Controller\Adminhtml\Report\Shopcart
+{
+    /**
+     * Products in carts action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Products in Carts'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_shopcart_product'
+        )->_addBreadcrumb(
+            __('Products Report'),
+            __('Products Report')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Reports\Block\Adminhtml\Shopcart\Product')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics.php
index 8886b6cd39300e65ed79da68b2ffd51256bde01b..7f44b988c10f3adebea0f8fa6fcc7d74edbcfe3e 100644
--- a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics.php
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics.php
@@ -71,48 +71,6 @@ class Statistics extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Report statistics action initialization operations
-     *
-     * @param array|\Magento\Framework\Object $blocks
-     * @return $this
-     */
-    public function _initReportAction($blocks)
-    {
-        if (!is_array($blocks)) {
-            $blocks = array($blocks);
-        }
-
-        $requestData = $this->_objectManager->get(
-            'Magento\Backend\Helper\Data'
-        )->prepareFilterString(
-            $this->getRequest()->getParam('filter')
-        );
-        $inputFilter = new \Zend_Filter_Input(
-            array('from' => $this->_dateFilter, 'to' => $this->_dateFilter),
-            array(),
-            $requestData
-        );
-        $requestData = $inputFilter->getUnescaped();
-        $requestData['store_ids'] = $this->getRequest()->getParam('store_ids');
-        $params = new \Magento\Framework\Object();
-
-        foreach ($requestData as $key => $value) {
-            if (!empty($value)) {
-                $params->setData($key, $value);
-            }
-        }
-
-        foreach ($blocks as $block) {
-            if ($block) {
-                $block->setPeriodType($params->getData('period_type'));
-                $block->setFilterData($params);
-            }
-        }
-
-        return $this;
-    }
-
     /**
      * Retrieve array of collection names by code specified in request
      *
@@ -149,81 +107,6 @@ class Statistics extends \Magento\Backend\App\Action
         return $out;
     }
 
-    /**
-     * Refresh statistics for last 25 hours
-     *
-     * @return void
-     */
-    public function refreshRecentAction()
-    {
-        try {
-            $collectionsNames = $this->_getCollectionNames();
-            /** @var \Magento\Framework\Stdlib\DateTime\DateInterface $currentDate */
-            $currentDate = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface')->date();
-            $date = $currentDate->subHour(25);
-            foreach ($collectionsNames as $collectionName) {
-                $this->_objectManager->create($collectionName)->aggregate($date);
-            }
-            $this->messageManager->addSuccess(__('Recent statistics have been updated.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t refresh recent statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        if ($this->_getSession()->isFirstPageAfterLogin()) {
-            $this->_redirect('adminhtml/*');
-        } else {
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl('*/*'));
-        }
-    }
-
-    /**
-     * Refresh statistics for all period
-     *
-     * @return void
-     */
-    public function refreshLifetimeAction()
-    {
-        try {
-            $collectionsNames = $this->_getCollectionNames();
-            foreach ($collectionsNames as $collectionName) {
-                $this->_objectManager->create($collectionName)->aggregate();
-            }
-            $this->messageManager->addSuccess(__('We updated lifetime statistics.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t refresh lifetime statistics.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        if ($this->_getSession()->isFirstPageAfterLogin()) {
-            $this->_redirect('adminhtml/*');
-        } else {
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl('*/*'));
-        }
-    }
-
-    /**
-     * Refresh statistics action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Refresh Statistics'));
-
-        $this->_initAction()->_setActiveMenu(
-            'Magento_Reports::report_statistics_refresh'
-        )->_addBreadcrumb(
-            __('Refresh Statistics'),
-            __('Refresh Statistics')
-        );
-        $this->_view->renderLayout();
-    }
-
     /**
      * Determine if action is allowed for reports module
      *
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b658cd05238aebf1d84aff110079f5acc3d174e2
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/Index.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Statistics;
+
+class Index extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
+{
+    /**
+     * Refresh statistics action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Refresh Statistics'));
+
+        $this->_initAction()->_setActiveMenu(
+            'Magento_Reports::report_statistics_refresh'
+        )->_addBreadcrumb(
+            __('Refresh Statistics'),
+            __('Refresh Statistics')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
new file mode 100644
index 0000000000000000000000000000000000000000..afdb7aefcfbe1d9a45a12af79e56ca1b8c2503ed
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshLifetime.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Statistics;
+
+use \Magento\Backend\Model\Session;
+
+class RefreshLifetime extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
+{
+    /**
+     * Refresh statistics for all period
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $collectionsNames = $this->_getCollectionNames();
+            foreach ($collectionsNames as $collectionName) {
+                $this->_objectManager->create($collectionName)->aggregate();
+            }
+            $this->messageManager->addSuccess(__('We updated lifetime statistics.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t refresh lifetime statistics.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        if ($this->_getSession()->isFirstPageAfterLogin()) {
+            $this->_redirect('adminhtml/*');
+        } else {
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl('*/*'));
+        }
+    }
+}
diff --git a/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
new file mode 100644
index 0000000000000000000000000000000000000000..319346f49dcdce408c51c941005b9e988e7d077d
--- /dev/null
+++ b/app/code/Magento/Reports/Controller/Adminhtml/Report/Statistics/RefreshRecent.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Reports\Controller\Adminhtml\Report\Statistics;
+
+use \Magento\Backend\Model\Session;
+
+class RefreshRecent extends \Magento\Reports\Controller\Adminhtml\Report\Statistics
+{
+    /**
+     * Refresh statistics for last 25 hours
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $collectionsNames = $this->_getCollectionNames();
+            /** @var \Magento\Framework\Stdlib\DateTime\DateInterface $currentDate */
+            $currentDate = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\TimezoneInterface')->date();
+            $date = $currentDate->subHour(25);
+            foreach ($collectionsNames as $collectionName) {
+                $this->_objectManager->create($collectionName)->aggregate($date);
+            }
+            $this->messageManager->addSuccess(__('Recent statistics have been updated.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t refresh recent statistics.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        if ($this->_getSession()->isFirstPageAfterLogin()) {
+            $this->_redirect('adminhtml/*');
+        } else {
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl('*/*'));
+        }
+    }
+}
diff --git a/app/code/Magento/Reports/etc/adminhtml/routes.xml b/app/code/Magento/Reports/etc/adminhtml/routes.xml
index a81e2cac98265e6b2d92f676b0ebbb477668278a..b5a1e82ffae7efec96ae9a7fd8d754dc2a92eb9d 100644
--- a/app/code/Magento/Reports/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Reports/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="reports" frontName="reports">
-            <module name="Magento_Reports_Adminhtml" before="Magento_Reports" />
+            <module name="Magento_Reports" before="Magento_Reports" />
         </route>
     </router>
-</config>
\ No newline at end of file
+</config>
diff --git a/app/code/Magento/Reports/view/adminhtml/layout/reports_index_search_block.xml b/app/code/Magento/Reports/view/adminhtml/layout/reports_index_search_block.xml
index 2a74289320d4089718102f1d141b070ac5ef796d..dc33589e6606a4200f5adcfee49f65c3a7791c47 100644
--- a/app/code/Magento/Reports/view/adminhtml/layout/reports_index_search_block.xml
+++ b/app/code/Magento/Reports/view/adminhtml/layout/reports_index_search_block.xml
@@ -78,6 +78,7 @@
                         <argument name="header" xsi:type="string" translate="true">Store</argument>
                         <argument name="index" xsi:type="string">store_id</argument>
                         <argument name="type" xsi:type="string">store</argument>
+                        <argument name="store_all" xsi:type="string">1</argument>
                         <argument name="store_view" xsi:type="string">1</argument>
                         <argument name="sortable" xsi:type="string">0</argument>
                         <argument name="column_css_class" xsi:type="string">col-store</argument>
diff --git a/app/code/Magento/Review/Block/Adminhtml/Add.php b/app/code/Magento/Review/Block/Adminhtml/Add.php
index 6450b8d3dc5446a5b78a23a59b6ad2cee8bbd510..efd84e7b86fd482c1b90693987e35236eb7f96b6 100644
--- a/app/code/Magento/Review/Block/Adminhtml/Add.php
+++ b/app/code/Magento/Review/Block/Adminhtml/Add.php
@@ -43,10 +43,10 @@ class Add extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml';
         $this->_mode = 'add';
 
-        $this->_updateButton('save', 'label', __('Save Review'));
-        $this->_updateButton('save', 'id', 'save_button');
+        $this->buttonList->update('save', 'label', __('Save Review'));
+        $this->buttonList->update('save', 'id', 'save_button');
 
-        $this->_updateButton('reset', 'id', 'reset_button');
+        $this->buttonList->update('reset', 'id', 'reset_button');
 
         $this->_formScripts[] = '
             toggleParentVis("add_review_form");
diff --git a/app/code/Magento/Review/Block/Adminhtml/Edit.php b/app/code/Magento/Review/Block/Adminhtml/Edit.php
index 9a541bec2faabe666262a2fbf32ea5cb52ba4c5c..37403652a54f6186673399f536e29ad393e0f378 100644
--- a/app/code/Magento/Review/Block/Adminhtml/Edit.php
+++ b/app/code/Magento/Review/Block/Adminhtml/Edit.php
@@ -50,14 +50,14 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_reviewFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Review\Model\ReviewFactory $reviewFactory
      * @param \Magento\Review\Helper\Action\Pager $reviewActionPager
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Review\Model\ReviewFactory $reviewFactory,
         \Magento\Review\Helper\Action\Pager $reviewActionPager,
         \Magento\Framework\Registry $registry,
@@ -149,12 +149,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                 105
             );
         }
-        $this->_updateButton('save', 'label', __('Save Review'));
-        $this->_updateButton('save', 'id', 'save_button');
-        $this->_updateButton('delete', 'label', __('Delete Review'));
+        $this->buttonList->update('save', 'label', __('Save Review'));
+        $this->buttonList->update('save', 'id', 'save_button');
+        $this->buttonList->update('delete', 'label', __('Delete Review'));
 
         if ($this->getRequest()->getParam('productId', false)) {
-            $this->_updateButton(
+            $this->buttonList->update(
                 'back',
                 'onclick',
                 'setLocation(\'' . $this->getUrl(
@@ -165,7 +165,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getRequest()->getParam('customerId', false)) {
-            $this->_updateButton(
+            $this->buttonList->update(
                 'back',
                 'onclick',
                 'setLocation(\'' . $this->getUrl(
@@ -176,8 +176,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getRequest()->getParam('ret', false) == 'pending') {
-            $this->_updateButton('back', 'onclick', 'setLocation(\'' . $this->getUrl('catalog/*/pending') . '\')');
-            $this->_updateButton(
+            $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getUrl('catalog/*/pending') . '\')');
+            $this->buttonList->update(
                 'delete',
                 'onclick',
                 'deleteConfirm(' . '\'' . __(
diff --git a/app/code/Magento/Review/Block/Adminhtml/Main.php b/app/code/Magento/Review/Block/Adminhtml/Main.php
index 67b90c5b1a1d447448fcd4425d3e47251281d6d3..9e3c951cdef86caaab91a85a76de89815c0d58a8 100644
--- a/app/code/Magento/Review/Block/Adminhtml/Main.php
+++ b/app/code/Magento/Review/Block/Adminhtml/Main.php
@@ -49,14 +49,14 @@ class Main extends \Magento\Backend\Block\Widget\Grid\Container
     protected $_productFactory;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Customer\Service\V1\CustomerAccountServiceInterface $customerAccount
      * @param \Magento\Catalog\Model\ProductFactory $productFactory
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Customer\Service\V1\CustomerAccountServiceInterface $customerAccount,
         \Magento\Catalog\Model\ProductFactory $productFactory,
         \Magento\Framework\Registry $registry,
@@ -102,7 +102,7 @@ class Main extends \Magento\Backend\Block\Widget\Grid\Container
             } else {
                 $this->_headerText = __('Pending Reviews');
             }
-            $this->_removeButton('add');
+            $this->buttonList->remove('add');
         } else {
             if ($customerName) {
                 $this->_headerText = __('All Reviews of Customer `%1`', $customerName);
diff --git a/app/code/Magento/Review/Block/Adminhtml/Rating/Edit.php b/app/code/Magento/Review/Block/Adminhtml/Rating/Edit.php
index 7043d560eaf5a777a8bff2a3cd51bc18f78de878..54438381abd6013cc5f8d83e9f40ab64c55bc927 100644
--- a/app/code/Magento/Review/Block/Adminhtml/Rating/Edit.php
+++ b/app/code/Magento/Review/Block/Adminhtml/Rating/Edit.php
@@ -48,13 +48,13 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_blockGroup = 'Magento_Review';
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Review\Model\RatingFactory $ratingFactory
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Review\Model\RatingFactory $ratingFactory,
         \Magento\Framework\Registry $registry,
         array $data = array()
@@ -74,8 +74,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $this->_controller = 'adminhtml_rating';
         $this->_blockGroup = 'Magento_Review';
 
-        $this->_updateButton('save', 'label', __('Save Rating'));
-        $this->_updateButton('delete', 'label', __('Delete Rating'));
+        $this->buttonList->update('save', 'label', __('Save Rating'));
+        $this->buttonList->update('delete', 'label', __('Delete Rating'));
 
         if ($this->getRequest()->getParam($this->_objectId)) {
             $ratingData = $this->_ratingFactory->create()->load($this->getRequest()->getParam($this->_objectId));
diff --git a/app/code/Magento/Review/Block/Product/View.php b/app/code/Magento/Review/Block/Product/View.php
index 72c8edfdb5de01c4b1835efa1f446fea4a5d33fd..5fc7f0e2bc93760a47e0fd8697f6cc84ad91c6c0 100644
--- a/app/code/Magento/Review/Block/Product/View.php
+++ b/app/code/Magento/Review/Block/Product/View.php
@@ -24,6 +24,7 @@
 namespace Magento\Review\Block\Product;
 
 use Magento\Review\Model\Resource\Review\Collection as ReviewCollection;
+use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
 
 /**
  * Product Reviews Page
@@ -56,6 +57,8 @@ class View extends \Magento\Catalog\Block\Product\View
      * @param \Magento\Catalog\Helper\Product $productHelper
      * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param TaxCalculationServiceInterface $taxCalculationService
      * @param \Magento\Review\Model\Resource\Review\CollectionFactory $collectionFactory
      * @param array $data
      */
@@ -69,6 +72,8 @@ class View extends \Magento\Catalog\Block\Product\View
         \Magento\Catalog\Helper\Product $productHelper,
         \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
+        \Magento\Customer\Model\Session $customerSession,
+        TaxCalculationServiceInterface $taxCalculationService,
         \Magento\Review\Model\Resource\Review\CollectionFactory $collectionFactory,
         array $data = array()
     ) {
@@ -83,6 +88,8 @@ class View extends \Magento\Catalog\Block\Product\View
             $productHelper,
             $productTypeConfig,
             $localeFormat,
+            $customerSession,
+            $taxCalculationService,
             $data
         );
     }
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product.php b/app/code/Magento/Review/Controller/Adminhtml/Product.php
index c96d02271c38b9f70b131f7ff57e8ac2eb0ce4e5..82b548fba47c52774131c98708c0ad6a89712776 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product.php
@@ -74,378 +74,6 @@ class Product extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Customer Reviews'));
-
-        $this->_title->add(__('Reviews'));
-
-        if ($this->getRequest()->getParam('ajax')) {
-            return $this->_forward('reviewGrid');
-        }
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
-
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Main'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function pendingAction()
-    {
-        $this->_title->add(__('Customer Reviews'));
-
-        $this->_title->add(__('Pending Reviews'));
-
-        if ($this->getRequest()->getParam('ajax')) {
-            $this->_coreRegistry->register('usePendingFilter', true);
-            return $this->_forward('reviewGrid');
-        }
-
-        $this->_view->loadLayout();
-
-        $this->_coreRegistry->register('usePendingFilter', true);
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Main'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Customer Reviews'));
-
-        $this->_title->add(__('Edit Review'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
-
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Edit'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_title->add(__('Customer Reviews'));
-
-        $this->_title->add(__('New Review'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
-
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Add'));
-        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Product\Grid'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return mixed
-     */
-    public function saveAction()
-    {
-        if (($data = $this->getRequest()->getPost()) && ($reviewId = $this->getRequest()->getParam('id'))) {
-            $review = $this->_reviewFactory->create()->load($reviewId);
-            if (!$review->getId()) {
-                $this->messageManager->addError(__('The review was removed by another user or does not exist.'));
-            } else {
-                try {
-                    $review->addData($data)->save();
-
-                    $arrRatingId = $this->getRequest()->getParam('ratings', array());
-                    $votes = $this->_objectManager->create(
-                        'Magento\Review\Model\Rating\Option\Vote'
-                    )->getResourceCollection()->setReviewFilter(
-                        $reviewId
-                    )->addOptionInfo()->load()->addRatingOptions();
-                    foreach ($arrRatingId as $ratingId => $optionId) {
-                        if ($vote = $votes->getItemByColumnValue('rating_id', $ratingId)) {
-                            $this->_ratingFactory->create(
-                            )->setVoteId(
-                                $vote->getId()
-                            )->setReviewId(
-                                $review->getId()
-                            )->updateOptionVote(
-                                $optionId
-                            );
-                        } else {
-                            $this->_ratingFactory->create(
-                            )->setRatingId(
-                                $ratingId
-                            )->setReviewId(
-                                $review->getId()
-                            )->addOptionVote(
-                                $optionId,
-                                $review->getEntityPkValue()
-                            );
-                        }
-                    }
-
-                    $review->aggregate();
-
-                    $this->messageManager->addSuccess(__('You saved the review.'));
-                } catch (\Magento\Framework\Model\Exception $e) {
-                    $this->messageManager->addError($e->getMessage());
-                } catch (\Exception $e) {
-                    $this->messageManager->addException($e, __('Something went wrong while saving this review.'));
-                }
-            }
-
-            $nextId = (int)$this->getRequest()->getParam('next_item');
-            $url = $this->getUrl($this->getRequest()->getParam('ret') == 'pending' ? '*/*/pending' : '*/*/');
-            if ($nextId) {
-                $url = $this->getUrl('review/*/edit', array('id' => $nextId));
-            }
-            return $this->getResponse()->setRedirect($url);
-        }
-        $this->_redirect('review/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $reviewId = $this->getRequest()->getParam('id', false);
-        try {
-            $this->_reviewFactory->create()->setId($reviewId)->aggregate()->delete();
-
-            $this->messageManager->addSuccess(__('The review has been deleted.'));
-            if ($this->getRequest()->getParam('ret') == 'pending') {
-                $this->getResponse()->setRedirect($this->getUrl('review/*/pending'));
-            } else {
-                $this->getResponse()->setRedirect($this->getUrl('review/*/'));
-            }
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Something went wrong  deleting this review.'));
-        }
-
-        $this->_redirect('review/*/edit/', array('id' => $reviewId));
-    }
-
-    /**
-     * @return void
-     */
-    public function massDeleteAction()
-    {
-        $reviewsIds = $this->getRequest()->getParam('reviews');
-
-        if (!is_array($reviewsIds)) {
-            $this->messageManager->addError(__('Please select review(s).'));
-        } else {
-            try {
-                foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_reviewFactory->create()->load($reviewId);
-                    $model->delete();
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 record(s) have been deleted.', count($reviewsIds))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while deleting record(s).'));
-            }
-        }
-
-        $this->_redirect('review/*/' . $this->getRequest()->getParam('ret', 'index'));
-    }
-
-    /**
-     * @return void
-     */
-    public function massUpdateStatusAction()
-    {
-        $reviewsIds = $this->getRequest()->getParam('reviews');
-        if (!is_array($reviewsIds)) {
-            $this->messageManager->addError(__('Please select review(s).'));
-        } else {
-            try {
-                $status = $this->getRequest()->getParam('status');
-                foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_reviewFactory->create()->load($reviewId);
-                    $model->setStatusId($status)->save()->aggregate();
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 record(s) have been updated.', count($reviewsIds))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('An error occurred while updating the selected review(s).')
-                );
-            }
-        }
-
-        $this->_redirect('review/*/' . $this->getRequest()->getParam('ret', 'index'));
-    }
-
-    /**
-     * @return void
-     */
-    public function massVisibleInAction()
-    {
-        $reviewsIds = $this->getRequest()->getParam('reviews');
-
-        if (!is_array($reviewsIds)) {
-            $this->messageManager->addError(__('Please select review(s).'));
-        } else {
-            try {
-                $stores = $this->getRequest()->getParam('stores');
-                foreach ($reviewsIds as $reviewId) {
-                    $model = $this->_reviewFactory->create()->load($reviewId);
-                    $model->setSelectStores($stores);
-                    $model->save();
-                }
-                $this->messageManager->addSuccess(
-                    __('A total of %1 record(s) have been updated.', count($reviewsIds))
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('An error occurred while updating the selected review(s).')
-                );
-            }
-        }
-
-        $this->_redirect('review/*/pending');
-    }
-
-    /**
-     * @return void
-     */
-    public function productGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Product\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * @return void
-     */
-    public function reviewGridAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Grid')->toHtml()
-        );
-    }
-
-    /**
-     * @return void
-     */
-    public function jsonProductInfoAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $id = $this->getRequest()->getParam('id');
-        if (intval($id) > 0) {
-            $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($id);
-
-            $response->setId($id);
-            $response->addData($product->getData());
-            $response->setError(0);
-        } else {
-            $response->setError(1);
-            $response->setMessage(__('We can\'t get the product ID.'));
-        }
-        $this->getResponse()->representJson($response->toJSON());
-    }
-
-    /**
-     * @return void
-     */
-    public function postAction()
-    {
-        $productId = $this->getRequest()->getParam('product_id', false);
-
-        if ($data = $this->getRequest()->getPost()) {
-            /** @var \Magento\Store\Model\StoreManagerInterface $storeManagerInterface */
-            $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
-            if ($storeManager->hasSingleStore()) {
-                $data['stores'] = array(
-                    $storeManager->getStore(true)->getId()
-                );
-            } elseif (isset($data['select_stores'])) {
-                $data['stores'] = $data['select_stores'];
-            }
-
-            $review = $this->_reviewFactory->create()->setData($data);
-
-            try {
-                $review->setEntityId(1) // product
-                    ->setEntityPkValue($productId)
-                    ->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID)
-                    ->setStatusId($data['status_id'])
-                    ->setCustomerId(null)//null is for administrator only
-                    ->save();
-
-                $arrRatingId = $this->getRequest()->getParam('ratings', array());
-                foreach ($arrRatingId as $ratingId => $optionId) {
-                    $this->_ratingFactory->create(
-                    )->setRatingId(
-                        $ratingId
-                    )->setReviewId(
-                        $review->getId()
-                    )->addOptionVote(
-                        $optionId,
-                        $productId
-                    );
-                }
-
-                $review->aggregate();
-
-                $this->messageManager->addSuccess(__('You saved the review.'));
-                if ($this->getRequest()->getParam('ret') == 'pending') {
-                    $this->getResponse()->setRedirect($this->getUrl('review/*/pending'));
-                } else {
-                    $this->getResponse()->setRedirect($this->getUrl('review/*/'));
-                }
-
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('An error occurred while saving review.'));
-            }
-        }
-        $this->getResponse()->setRedirect($this->getUrl('review/*/'));
-        return;
-    }
-
-    /**
-     * @return void
-     */
-    public function ratingItemsAction()
-    {
-        $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Review\Block\Adminhtml\Rating\Detailed'
-            )->setIndependentMode()->toHtml()
-        );
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Delete.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d2a31695f55547f49306e94305eb2b85d544a75
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Delete.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Delete extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $reviewId = $this->getRequest()->getParam('id', false);
+        try {
+            $this->_reviewFactory->create()->setId($reviewId)->aggregate()->delete();
+
+            $this->messageManager->addSuccess(__('The review has been deleted.'));
+            if ($this->getRequest()->getParam('ret') == 'pending') {
+                $this->getResponse()->setRedirect($this->getUrl('review/*/pending'));
+            } else {
+                $this->getResponse()->setRedirect($this->getUrl('review/*/'));
+            }
+            return;
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Something went wrong  deleting this review.'));
+        }
+
+        $this->_redirect('review/*/edit/', array('id' => $reviewId));
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ef7f201b65fd3944f5b7e7d64dde22e73e059a9
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Edit.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Edit extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Reviews'));
+
+        $this->_title->add(__('Edit Review'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
+
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Edit'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..e8e94acf9a41ef2c317f989910bfa32376056d7f
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Index.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Index extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Reviews'));
+
+        $this->_title->add(__('Reviews'));
+
+        if ($this->getRequest()->getParam('ajax')) {
+            return $this->_forward('reviewGrid');
+        }
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
+
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Main'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php
new file mode 100644
index 0000000000000000000000000000000000000000..977a2d3e6d3fdc8539c4c31a000f711a10212161
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/JsonProductInfo.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class JsonProductInfo extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $id = $this->getRequest()->getParam('id');
+        if (intval($id) > 0) {
+            $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($id);
+
+            $response->setId($id);
+            $response->addData($product->getData());
+            $response->setError(0);
+        } else {
+            $response->setError(1);
+            $response->setMessage(__('We can\'t get the product ID.'));
+        }
+        $this->getResponse()->representJson($response->toJSON());
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/MassDelete.php b/app/code/Magento/Review/Controller/Adminhtml/Product/MassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..424a2b7bcb89eff9d9289bade928968f1a6247f7
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/MassDelete.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class MassDelete extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $reviewsIds = $this->getRequest()->getParam('reviews');
+
+        if (!is_array($reviewsIds)) {
+            $this->messageManager->addError(__('Please select review(s).'));
+        } else {
+            try {
+                foreach ($reviewsIds as $reviewId) {
+                    $model = $this->_reviewFactory->create()->load($reviewId);
+                    $model->delete();
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 record(s) have been deleted.', count($reviewsIds))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while deleting record(s).'));
+            }
+        }
+
+        $this->_redirect('review/*/' . $this->getRequest()->getParam('ret', 'index'));
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/MassUpdateStatus.php b/app/code/Magento/Review/Controller/Adminhtml/Product/MassUpdateStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..e8db9cba6f612b588c0549017bfa9e669b8bc026
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/MassUpdateStatus.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class MassUpdateStatus extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $reviewsIds = $this->getRequest()->getParam('reviews');
+        if (!is_array($reviewsIds)) {
+            $this->messageManager->addError(__('Please select review(s).'));
+        } else {
+            try {
+                $status = $this->getRequest()->getParam('status');
+                foreach ($reviewsIds as $reviewId) {
+                    $model = $this->_reviewFactory->create()->load($reviewId);
+                    $model->setStatusId($status)->save()->aggregate();
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 record(s) have been updated.', count($reviewsIds))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('An error occurred while updating the selected review(s).')
+                );
+            }
+        }
+
+        $this->_redirect('review/*/' . $this->getRequest()->getParam('ret', 'index'));
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/MassVisibleIn.php b/app/code/Magento/Review/Controller/Adminhtml/Product/MassVisibleIn.php
new file mode 100644
index 0000000000000000000000000000000000000000..cd564490ee530c5f5aca30c859ecc0162fed9ac2
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/MassVisibleIn.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class MassVisibleIn extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $reviewsIds = $this->getRequest()->getParam('reviews');
+
+        if (!is_array($reviewsIds)) {
+            $this->messageManager->addError(__('Please select review(s).'));
+        } else {
+            try {
+                $stores = $this->getRequest()->getParam('stores');
+                foreach ($reviewsIds as $reviewId) {
+                    $model = $this->_reviewFactory->create()->load($reviewId);
+                    $model->setSelectStores($stores);
+                    $model->save();
+                }
+                $this->messageManager->addSuccess(
+                    __('A total of %1 record(s) have been updated.', count($reviewsIds))
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('An error occurred while updating the selected review(s).')
+                );
+            }
+        }
+
+        $this->_redirect('review/*/pending');
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..025f8c620ecccbaed3396ea27b1bab1782c60151
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/NewAction.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class NewAction extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Reviews'));
+
+        $this->_title->add(__('New Review'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_reviews_all');
+
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Add'));
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Product\Grid'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Pending.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Pending.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b6939cedb65f12132e276fc71532698f0fa358a
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Pending.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Pending extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Customer Reviews'));
+
+        $this->_title->add(__('Pending Reviews'));
+
+        if ($this->getRequest()->getParam('ajax')) {
+            $this->_coreRegistry->register('usePendingFilter', true);
+            return $this->_forward('reviewGrid');
+        }
+
+        $this->_view->loadLayout();
+
+        $this->_coreRegistry->register('usePendingFilter', true);
+        $this->_addContent($this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Main'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php
new file mode 100644
index 0000000000000000000000000000000000000000..72eefddbba5970b39c83b369a4b137d01e9a2ab3
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Post.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Post extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $productId = $this->getRequest()->getParam('product_id', false);
+
+        if ($data = $this->getRequest()->getPost()) {
+            /** @var \Magento\Store\Model\StoreManagerInterface $storeManagerInterface */
+            $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
+            if ($storeManager->hasSingleStore()) {
+                $data['stores'] = array(
+                    $storeManager->getStore(true)->getId()
+                );
+            } elseif (isset($data['select_stores'])) {
+                $data['stores'] = $data['select_stores'];
+            }
+
+            $review = $this->_reviewFactory->create()->setData($data);
+
+            try {
+                $review->setEntityId(1) // product
+                    ->setEntityPkValue($productId)
+                    ->setStoreId(\Magento\Store\Model\Store::DEFAULT_STORE_ID)
+                    ->setStatusId($data['status_id'])
+                    ->setCustomerId(null)//null is for administrator only
+                    ->save();
+
+                $arrRatingId = $this->getRequest()->getParam('ratings', array());
+                foreach ($arrRatingId as $ratingId => $optionId) {
+                    $this->_ratingFactory->create(
+                    )->setRatingId(
+                        $ratingId
+                    )->setReviewId(
+                        $review->getId()
+                    )->addOptionVote(
+                        $optionId,
+                        $productId
+                    );
+                }
+
+                $review->aggregate();
+
+                $this->messageManager->addSuccess(__('You saved the review.'));
+                if ($this->getRequest()->getParam('ret') == 'pending') {
+                    $this->getResponse()->setRedirect($this->getUrl('review/*/pending'));
+                } else {
+                    $this->getResponse()->setRedirect($this->getUrl('review/*/'));
+                }
+
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('An error occurred while saving review.'));
+            }
+        }
+        $this->getResponse()->setRedirect($this->getUrl('review/*/'));
+        return;
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php b/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..b80f4461f38e1e283ea7d5bb72d42b7e2ec1aeaa
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/ProductGrid.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class ProductGrid extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Product\Grid')->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php b/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php
new file mode 100644
index 0000000000000000000000000000000000000000..95d021196f04d6c2de61c0888148527420fbc198
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/RatingItems.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class RatingItems extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Review\Block\Adminhtml\Rating\Detailed'
+            )->setIndependentMode()->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/ReviewGrid.php b/app/code/Magento/Review/Controller/Adminhtml/Product/ReviewGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..5651d5d8d5532d85e6e6ea082e0b15d8aefeca50
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/ReviewGrid.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class ReviewGrid extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Grid')->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Reviews.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Reviews/Grid.php
similarity index 90%
rename from app/code/Magento/Review/Controller/Adminhtml/Product/Reviews.php
rename to app/code/Magento/Review/Controller/Adminhtml/Product/Reviews/Grid.php
index ace0dc0a0dc32bb319168522dc423193e48aec1a..a576637393d7d7de41abb0140b3140bb410c91b9 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Product/Reviews.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Reviews/Grid.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Review\Controller\Adminhtml\Product;
+namespace Magento\Review\Controller\Adminhtml\Product\Reviews;
 
-class Reviews extends \Magento\Backend\App\Action
+class Grid extends \Magento\Backend\App\Action
 {
     /**
      * @var \Magento\Catalog\Controller\Adminhtml\Product\Builder
@@ -39,7 +40,7 @@ class Reviews extends \Magento\Backend\App\Action
         \Magento\Catalog\Controller\Adminhtml\Product\Builder $productBuilder
     ) {
         $this->productBuilder = $productBuilder;
-         parent::__construct($context);
+        parent::__construct($context);
     }
 
     /**
@@ -47,7 +48,7 @@ class Reviews extends \Magento\Backend\App\Action
      *
      * @return void
      */
-    public function gridAction()
+    public function execute()
     {
         $product = $this->productBuilder->build($this->getRequest());
         $this->_view->loadLayout();
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad3cad8612ad39d895b18be4955834f10b86f9ac
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Product/Save.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Product;
+
+class Save extends \Magento\Review\Controller\Adminhtml\Product
+{
+    /**
+     * @return mixed
+     */
+    public function execute()
+    {
+        if (($data = $this->getRequest()->getPost()) && ($reviewId = $this->getRequest()->getParam('id'))) {
+            $review = $this->_reviewFactory->create()->load($reviewId);
+            if (!$review->getId()) {
+                $this->messageManager->addError(__('The review was removed by another user or does not exist.'));
+            } else {
+                try {
+                    $review->addData($data)->save();
+
+                    $arrRatingId = $this->getRequest()->getParam('ratings', array());
+                    $votes = $this->_objectManager->create(
+                        'Magento\Review\Model\Rating\Option\Vote'
+                    )->getResourceCollection()->setReviewFilter(
+                        $reviewId
+                    )->addOptionInfo()->load()->addRatingOptions();
+                    foreach ($arrRatingId as $ratingId => $optionId) {
+                        if ($vote = $votes->getItemByColumnValue('rating_id', $ratingId)) {
+                            $this->_ratingFactory->create(
+                            )->setVoteId(
+                                $vote->getId()
+                            )->setReviewId(
+                                $review->getId()
+                            )->updateOptionVote(
+                                $optionId
+                            );
+                        } else {
+                            $this->_ratingFactory->create(
+                            )->setRatingId(
+                                $ratingId
+                            )->setReviewId(
+                                $review->getId()
+                            )->addOptionVote(
+                                $optionId,
+                                $review->getEntityPkValue()
+                            );
+                        }
+                    }
+
+                    $review->aggregate();
+
+                    $this->messageManager->addSuccess(__('You saved the review.'));
+                } catch (\Magento\Framework\Model\Exception $e) {
+                    $this->messageManager->addError($e->getMessage());
+                } catch (\Exception $e) {
+                    $this->messageManager->addException($e, __('Something went wrong while saving this review.'));
+                }
+            }
+
+            $nextId = (int)$this->getRequest()->getParam('next_item');
+            $url = $this->getUrl($this->getRequest()->getParam('ret') == 'pending' ? '*/*/pending' : '*/*/');
+            if ($nextId) {
+                $url = $this->getUrl('review/*/edit', array('id' => $nextId));
+            }
+            return $this->getResponse()->setRedirect($url);
+        }
+        $this->_redirect('review/*/');
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating.php b/app/code/Magento/Review/Controller/Adminhtml/Rating.php
index 21e9c28ad4d7bda1d052d7e520601029e34b2e33..cac0c2faca5f5a7d2e6f5f05998d6ee7d1c1dce7 100644
--- a/app/code/Magento/Review/Controller/Adminhtml/Rating.php
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating.php
@@ -47,149 +47,6 @@ class Rating extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_initEnityId();
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_ratings');
-        $this->_addBreadcrumb(__('Manage Ratings'), __('Manage Ratings'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_initEnityId();
-        $this->_view->loadLayout();
-
-        $ratingModel = $this->_objectManager->create('Magento\Review\Model\Rating');
-        if ($this->getRequest()->getParam('id')) {
-            $ratingModel->load($this->getRequest()->getParam('id'));
-        }
-
-        $this->_title->add($ratingModel->getId() ? $ratingModel->getRatingCode() : __('New Rating'));
-
-        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_ratings');
-        $this->_addBreadcrumb(__('Manage Ratings'), __('Manage Ratings'));
-
-        $this->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Rating\Edit')
-        )->_addLeft(
-            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Rating\Edit\Tabs')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Save rating
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $this->_initEnityId();
-
-        if ($this->getRequest()->getPost()) {
-            try {
-                $ratingModel = $this->_objectManager->create('Magento\Review\Model\Rating');
-
-                $stores = $this->getRequest()->getParam('stores');
-                $position = (int)$this->getRequest()->getParam('position');
-                $stores[] = 0;
-                $isActive = (bool)$this->getRequest()->getParam('is_active');
-                $ratingModel->setRatingCode(
-                    $this->getRequest()->getParam('rating_code')
-                )->setRatingCodes(
-                    $this->getRequest()->getParam('rating_codes')
-                )->setStores(
-                    $stores
-                )->setPosition(
-                    $position
-                )->setId(
-                    $this->getRequest()->getParam('id')
-                )->setIsActive(
-                    $isActive
-                )->setEntityId(
-                    $this->_coreRegistry->registry('entityId')
-                )->save();
-
-                $options = $this->getRequest()->getParam('option_title');
-
-                if (is_array($options)) {
-                    $i = 1;
-                    foreach ($options as $key => $optionCode) {
-                        $optionModel = $this->_objectManager->create('Magento\Review\Model\Rating\Option');
-                        if (!preg_match("/^add_([0-9]*?)$/", $key)) {
-                            $optionModel->setId($key);
-                        }
-
-                        $optionModel->setCode(
-                            $optionCode
-                        )->setValue(
-                            $i
-                        )->setRatingId(
-                            $ratingModel->getId()
-                        )->setPosition(
-                            $i
-                        )->save();
-                        $i++;
-                    }
-                }
-
-                $this->messageManager->addSuccess(__('You saved the rating.'));
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setRatingData(false);
-
-                $this->_redirect('review/rating/');
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_objectManager->get(
-                    'Magento\Backend\Model\Session'
-                )->setRatingData(
-                    $this->getRequest()->getPost()
-                );
-                $this->_redirect('review/rating/edit', array('id' => $this->getRequest()->getParam('id')));
-                return;
-            }
-        }
-        $this->_redirect('review/rating/');
-    }
-
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        if ($this->getRequest()->getParam('id') > 0) {
-            try {
-                $model = $this->_objectManager->create('Magento\Review\Model\Rating');
-                /* @var $model \Magento\Review\Model\Rating */
-                $model->load($this->getRequest()->getParam('id'))->delete();
-                $this->messageManager->addSuccess(__('You deleted the rating.'));
-                $this->_redirect('review/rating/');
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('review/rating/edit', array('id' => $this->getRequest()->getParam('id')));
-            }
-        }
-        $this->_redirect('review/rating/');
-    }
-
     /**
      * @return void
      */
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..45bebe4475b482d6e43f9e152cd5351d6a3af670
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Delete.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Rating;
+
+class Delete extends \Magento\Review\Controller\Adminhtml\Rating
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getParam('id') > 0) {
+            try {
+                $model = $this->_objectManager->create('Magento\Review\Model\Rating');
+                /* @var $model \Magento\Review\Model\Rating */
+                $model->load($this->getRequest()->getParam('id'))->delete();
+                $this->messageManager->addSuccess(__('You deleted the rating.'));
+                $this->_redirect('review/rating/');
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('review/rating/edit', array('id' => $this->getRequest()->getParam('id')));
+            }
+        }
+        $this->_redirect('review/rating/');
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d9f54281d6c39ee46630ea0fe55bda370786a74
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Edit.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Rating;
+
+class Edit extends \Magento\Review\Controller\Adminhtml\Rating
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initEnityId();
+        $this->_view->loadLayout();
+
+        $ratingModel = $this->_objectManager->create('Magento\Review\Model\Rating');
+        if ($this->getRequest()->getParam('id')) {
+            $ratingModel->load($this->getRequest()->getParam('id'));
+        }
+
+        $this->_title->add($ratingModel->getId() ? $ratingModel->getRatingCode() : __('New Rating'));
+
+        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_ratings');
+        $this->_addBreadcrumb(__('Manage Ratings'), __('Manage Ratings'));
+
+        $this->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Rating\Edit')
+        )->_addLeft(
+            $this->_view->getLayout()->createBlock('Magento\Review\Block\Adminhtml\Rating\Edit\Tabs')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ad5fc221db78e7fa7c0458030a963d3b1921eac
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Rating;
+
+class Index extends \Magento\Review\Controller\Adminhtml\Rating
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initEnityId();
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Review::catalog_reviews_ratings_ratings');
+        $this->_addBreadcrumb(__('Manage Ratings'), __('Manage Ratings'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4f64c42cc45996a66a3919b96fb97b5dc041ee5
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Rating;
+
+class NewAction extends \Magento\Review\Controller\Adminhtml\Rating
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php b/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..136244e0f9b7296504ed48a4aa8a321791a47d76
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Adminhtml/Rating/Save.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Adminhtml\Rating;
+
+class Save extends \Magento\Review\Controller\Adminhtml\Rating
+{
+    /**
+     * Save rating
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initEnityId();
+
+        if ($this->getRequest()->getPost()) {
+            try {
+                $ratingModel = $this->_objectManager->create('Magento\Review\Model\Rating');
+
+                $stores = $this->getRequest()->getParam('stores');
+                $position = (int)$this->getRequest()->getParam('position');
+                $stores[] = 0;
+                $isActive = (bool)$this->getRequest()->getParam('is_active');
+                $ratingModel->setRatingCode(
+                    $this->getRequest()->getParam('rating_code')
+                )->setRatingCodes(
+                    $this->getRequest()->getParam('rating_codes')
+                )->setStores(
+                    $stores
+                )->setPosition(
+                    $position
+                )->setId(
+                    $this->getRequest()->getParam('id')
+                )->setIsActive(
+                    $isActive
+                )->setEntityId(
+                    $this->_coreRegistry->registry('entityId')
+                )->save();
+
+                $options = $this->getRequest()->getParam('option_title');
+
+                if (is_array($options)) {
+                    $i = 1;
+                    foreach ($options as $key => $optionCode) {
+                        $optionModel = $this->_objectManager->create('Magento\Review\Model\Rating\Option');
+                        if (!preg_match("/^add_([0-9]*?)$/", $key)) {
+                            $optionModel->setId($key);
+                        }
+
+                        $optionModel->setCode(
+                            $optionCode
+                        )->setValue(
+                            $i
+                        )->setRatingId(
+                            $ratingModel->getId()
+                        )->setPosition(
+                            $i
+                        )->save();
+                        $i++;
+                    }
+                }
+
+                $this->messageManager->addSuccess(__('You saved the rating.'));
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setRatingData(false);
+
+                $this->_redirect('review/rating/');
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_objectManager->get(
+                    'Magento\Backend\Model\Session'
+                )->setRatingData(
+                    $this->getRequest()->getPost()
+                );
+                $this->_redirect('review/rating/edit', array('id' => $this->getRequest()->getParam('id')));
+                return;
+            }
+        }
+        $this->_redirect('review/rating/');
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Customer.php b/app/code/Magento/Review/Controller/Customer.php
index f3e9ac268e3b78296832fd0b8b40c0521f72a874..fde3316fed5e5da004fd85efa4eacb0877026f2e 100644
--- a/app/code/Magento/Review/Controller/Customer.php
+++ b/app/code/Magento/Review/Controller/Customer.php
@@ -43,8 +43,10 @@ class Customer extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Customer\Model\Session $customerSession
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Customer\Model\Session $customerSession)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession
+    ) {
         $this->_customerSession = $customerSession;
         parent::__construct($context);
     }
@@ -62,41 +64,4 @@ class Customer extends \Magento\Framework\App\Action\Action
         }
         return parent::dispatch($request);
     }
-
-    /**
-     * Render my product reviews
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        if ($navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation')) {
-            $navigationBlock->setActive('review/customer');
-        }
-        if ($block = $this->_view->getLayout()->getBlock('review_customer_list')) {
-            $block->setRefererUrl($this->_redirect->getRefererUrl());
-        }
-
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Product Reviews'));
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Render review details
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $this->_view->loadLayout();
-        if ($navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation')) {
-            $navigationBlock->setActive('review/customer');
-        }
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Review Details'));
-        $this->_view->renderLayout();
-    }
 }
diff --git a/app/code/Magento/Review/Controller/Customer/Index.php b/app/code/Magento/Review/Controller/Customer/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f54fa22e80b71b09694f4b2103e1994048252276
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Customer/Index.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Customer;
+
+class Index extends \Magento\Review\Controller\Customer
+{
+    /**
+     * Render my product reviews
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        if ($navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation')) {
+            $navigationBlock->setActive('review/customer');
+        }
+        if ($block = $this->_view->getLayout()->getBlock('review_customer_list')) {
+            $block->setRefererUrl($this->_redirect->getRefererUrl());
+        }
+
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('My Product Reviews'));
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Customer/View.php b/app/code/Magento/Review/Controller/Customer/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..14d2be50a4f79cf714cfc67e746ae359ae72c8c3
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Customer/View.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Customer;
+
+class View extends \Magento\Review\Controller\Customer
+{
+    /**
+     * Render review details
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        if ($navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation')) {
+            $navigationBlock->setActive('review/customer');
+        }
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('Review Details'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Product.php b/app/code/Magento/Review/Controller/Product.php
index 448350cb499470fdd3894e7d09c7051e4a30eea4..cd735d1fe62caf8ebe89456ff6893e8a76fb131a 100644
--- a/app/code/Magento/Review/Controller/Product.php
+++ b/app/code/Magento/Review/Controller/Product.php
@@ -248,199 +248,4 @@ class Product extends \Magento\Framework\App\Action\Action
 
         return $product;
     }
-
-    /**
-     * Load review model with data by passed id.
-     * Return false if review was not loaded or review is not approved.
-     *
-     * @param int $reviewId
-     * @return bool|Review
-     */
-    protected function _loadReview($reviewId)
-    {
-        if (!$reviewId) {
-            return false;
-        }
-
-        $review = $this->_reviewFactory->create()->load($reviewId);
-        /* @var $review Review */
-        if (!$review->getId() || !$review->isApproved() || !$review->isAvailableOnStore(
-            $this->_storeManager->getStore()
-        )
-        ) {
-            return false;
-        }
-
-        $this->_coreRegistry->register('current_review', $review);
-
-        return $review;
-    }
-
-    /**
-     * Submit new review action
-     *
-     * @return void
-     */
-    public function postAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            return;
-        }
-
-        $data = $this->_reviewSession->getFormData(true);
-        if ($data) {
-            $rating = array();
-            if (isset($data['ratings']) && is_array($data['ratings'])) {
-                $rating = $data['ratings'];
-            }
-        } else {
-            $data = $this->getRequest()->getPost();
-            $rating = $this->getRequest()->getParam('ratings', array());
-        }
-
-        if (($product = $this->_initProduct()) && !empty($data)) {
-            $review = $this->_reviewFactory->create()->setData($data);
-            /* @var $review Review */
-
-            $validate = $review->validate();
-            if ($validate === true) {
-                try {
-                    $review->setEntityId(
-                        $review->getEntityIdByCode(Review::ENTITY_PRODUCT_CODE)
-                    )->setEntityPkValue(
-                        $product->getId()
-                    )->setStatusId(
-                        Review::STATUS_PENDING
-                    )->setCustomerId(
-                        $this->_customerSession->getCustomerId()
-                    )->setStoreId(
-                        $this->_storeManager->getStore()->getId()
-                    )->setStores(
-                        array($this->_storeManager->getStore()->getId())
-                    )->save();
-
-                    foreach ($rating as $ratingId => $optionId) {
-                        $this->_ratingFactory->create()->setRatingId(
-                            $ratingId
-                        )->setReviewId(
-                            $review->getId()
-                        )->setCustomerId(
-                            $this->_customerSession->getCustomerId()
-                        )->addOptionVote(
-                            $optionId,
-                            $product->getId()
-                        );
-                    }
-
-                    $review->aggregate();
-                    $this->messageManager->addSuccess(__('Your review has been accepted for moderation.'));
-                } catch (\Exception $e) {
-                    $this->_reviewSession->setFormData($data);
-                    $this->messageManager->addError(__('We cannot post the review.'));
-                }
-            } else {
-                $this->_reviewSession->setFormData($data);
-                if (is_array($validate)) {
-                    foreach ($validate as $errorMessage) {
-                        $this->messageManager->addError($errorMessage);
-                    }
-                } else {
-                    $this->messageManager->addError(__('We cannot post the review.'));
-                }
-            }
-        }
-
-        $redirectUrl = $this->_reviewSession->getRedirectUrl(true);
-        if ($redirectUrl) {
-            $this->getResponse()->setRedirect($redirectUrl);
-            return;
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
-    }
-
-    /**
-     * Show list of product's reviews
-     *
-     * @return void
-     */
-    public function listAction()
-    {
-        $product = $this->_initProduct();
-        if ($product) {
-            $this->_coreRegistry->register('productId', $product->getId());
-
-            $design = $this->_catalogDesign;
-            $settings = $design->getDesignSettings($product);
-            if ($settings->getCustomDesign()) {
-                $design->applyCustomDesign($settings->getCustomDesign());
-            }
-            $this->_initProductLayout($product);
-
-            // update breadcrumbs
-            $breadcrumbsBlock = $this->_view->getLayout()->getBlock('breadcrumbs');
-            if ($breadcrumbsBlock) {
-                $breadcrumbsBlock->addCrumb(
-                    'product',
-                    array('label' => $product->getName(), 'link' => $product->getProductUrl(), 'readonly' => true)
-                );
-                $breadcrumbsBlock->addCrumb('reviews', array('label' => __('Product Reviews')));
-            }
-
-            $this->_view->renderLayout();
-        } elseif (!$this->getResponse()->isRedirect()) {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Show details of one review
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $review = $this->_loadReview((int)$this->getRequest()->getParam('id'));
-        if (!$review) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        $product = $this->_loadProduct($review->getEntityPkValue());
-        if (!$product) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Load specific layout handles by product type id
-     *
-     * @param Product $product
-     * @return void
-     */
-    protected function _initProductLayout($product)
-    {
-        $update = $this->_view->getLayout()->getUpdate();
-        $update->addHandle('default');
-        $this->_view->addPageLayoutHandles(
-            array('id' => $product->getId(), 'sku' => $product->getSku(), 'type' => $product->getTypeId())
-        );
-
-        if ($product->getPageLayout()) {
-            $this->_objectManager->get('Magento\Theme\Helper\Layout')->applyHandle($product->getPageLayout());
-        }
-        $this->_view->loadLayoutUpdates();
-
-        if ($product->getPageLayout()) {
-            $this->_objectManager->get('Magento\Theme\Helper\Layout')->applyTemplate($product->getPageLayout());
-        }
-        $update->addUpdate($product->getCustomLayoutUpdate());
-        $this->_view->generateLayoutXml();
-        $this->_view->generateLayoutBlocks();
-    }
 }
diff --git a/app/code/Magento/Review/Controller/Product/ListAction.php b/app/code/Magento/Review/Controller/Product/ListAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..c91277db4356ac38a1c5a7f03ebe4ca3e0458e62
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Product/ListAction.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Product;
+
+use \Magento\Review\Model\Review;
+use Magento\Catalog\Model\Product as CatalogProduct;
+
+class ListAction extends \Magento\Review\Controller\Product
+{
+    /**
+     * Load specific layout handles by product type id
+     *
+     * @param CatalogProduct $product
+     * @return void
+     */
+    protected function _initProductLayout($product)
+    {
+        $update = $this->_view->getLayout()->getUpdate();
+        $update->addHandle('default');
+        $this->_view->addPageLayoutHandles(
+            array('id' => $product->getId(), 'sku' => $product->getSku(), 'type' => $product->getTypeId())
+        );
+
+        if ($product->getPageLayout()) {
+            $this->_objectManager->get('Magento\Theme\Helper\Layout')->applyHandle($product->getPageLayout());
+        }
+        $this->_view->loadLayoutUpdates();
+
+        if ($product->getPageLayout()) {
+            $this->_objectManager->get('Magento\Theme\Helper\Layout')->applyTemplate($product->getPageLayout());
+        }
+        $update->addUpdate($product->getCustomLayoutUpdate());
+        $this->_view->generateLayoutXml();
+        $this->_view->generateLayoutBlocks();
+    }
+
+    /**
+     * Show list of product's reviews
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $product = $this->_initProduct();
+        if ($product) {
+            $this->_coreRegistry->register('productId', $product->getId());
+
+            $design = $this->_catalogDesign;
+            $settings = $design->getDesignSettings($product);
+            if ($settings->getCustomDesign()) {
+                $design->applyCustomDesign($settings->getCustomDesign());
+            }
+            $this->_initProductLayout($product);
+
+            // update breadcrumbs
+            $breadcrumbsBlock = $this->_view->getLayout()->getBlock('breadcrumbs');
+            if ($breadcrumbsBlock) {
+                $breadcrumbsBlock->addCrumb(
+                    'product',
+                    array('label' => $product->getName(), 'link' => $product->getProductUrl(), 'readonly' => true)
+                );
+                $breadcrumbsBlock->addCrumb('reviews', array('label' => __('Product Reviews')));
+            }
+
+            $this->_view->renderLayout();
+        } elseif (!$this->getResponse()->isRedirect()) {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Product/Post.php b/app/code/Magento/Review/Controller/Product/Post.php
new file mode 100644
index 0000000000000000000000000000000000000000..e9c4a38888b0406c5753e70adf84b3990bdbdd0c
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Product/Post.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Product;
+
+use \Magento\Review\Model\Review;
+
+class Post extends \Magento\Review\Controller\Product
+{
+    /**
+     * Submit new review action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+            return;
+        }
+
+        $data = $this->_reviewSession->getFormData(true);
+        if ($data) {
+            $rating = array();
+            if (isset($data['ratings']) && is_array($data['ratings'])) {
+                $rating = $data['ratings'];
+            }
+        } else {
+            $data = $this->getRequest()->getPost();
+            $rating = $this->getRequest()->getParam('ratings', array());
+        }
+
+        if (($product = $this->_initProduct()) && !empty($data)) {
+            $review = $this->_reviewFactory->create()->setData($data);
+            /* @var $review Review */
+
+            $validate = $review->validate();
+            if ($validate === true) {
+                try {
+                    $review->setEntityId(
+                        $review->getEntityIdByCode(Review::ENTITY_PRODUCT_CODE)
+                    )->setEntityPkValue(
+                        $product->getId()
+                    )->setStatusId(
+                        Review::STATUS_PENDING
+                    )->setCustomerId(
+                        $this->_customerSession->getCustomerId()
+                    )->setStoreId(
+                        $this->_storeManager->getStore()->getId()
+                    )->setStores(
+                        array($this->_storeManager->getStore()->getId())
+                    )->save();
+
+                    foreach ($rating as $ratingId => $optionId) {
+                        $this->_ratingFactory->create()->setRatingId(
+                            $ratingId
+                        )->setReviewId(
+                            $review->getId()
+                        )->setCustomerId(
+                            $this->_customerSession->getCustomerId()
+                        )->addOptionVote(
+                            $optionId,
+                            $product->getId()
+                        );
+                    }
+
+                    $review->aggregate();
+                    $this->messageManager->addSuccess(__('Your review has been accepted for moderation.'));
+                } catch (\Exception $e) {
+                    $this->_reviewSession->setFormData($data);
+                    $this->messageManager->addError(__('We cannot post the review.'));
+                }
+            } else {
+                $this->_reviewSession->setFormData($data);
+                if (is_array($validate)) {
+                    foreach ($validate as $errorMessage) {
+                        $this->messageManager->addError($errorMessage);
+                    }
+                } else {
+                    $this->messageManager->addError(__('We cannot post the review.'));
+                }
+            }
+        }
+
+        $redirectUrl = $this->_reviewSession->getRedirectUrl(true);
+        if ($redirectUrl) {
+            $this->getResponse()->setRedirect($redirectUrl);
+            return;
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl());
+    }
+}
diff --git a/app/code/Magento/Review/Controller/Product/View.php b/app/code/Magento/Review/Controller/Product/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..793e5f7bf55de6a7ec0649cfed3e970283c41d14
--- /dev/null
+++ b/app/code/Magento/Review/Controller/Product/View.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Review\Controller\Product;
+
+use \Magento\Review\Model\Review;
+
+class View extends \Magento\Review\Controller\Product
+{
+    /**
+     * Load review model with data by passed id.
+     * Return false if review was not loaded or review is not approved.
+     *
+     * @param int $reviewId
+     * @return bool|Review
+     */
+    protected function _loadReview($reviewId)
+    {
+        if (!$reviewId) {
+            return false;
+        }
+
+        $review = $this->_reviewFactory->create()->load($reviewId);
+        /* @var $review Review */
+        if (!$review->getId()
+            || !$review->isApproved()
+            || !$review->isAvailableOnStore($this->_storeManager->getStore())
+        ) {
+            return false;
+        }
+
+        $this->_coreRegistry->register('current_review', $review);
+
+        return $review;
+    }
+
+    /**
+     * Show details of one review
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $review = $this->_loadReview((int)$this->getRequest()->getParam('id'));
+        if (!$review) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $product = $this->_loadProduct($review->getEntityPkValue());
+        if (!$product) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php b/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php
new file mode 100644
index 0000000000000000000000000000000000000000..e7abd7228b06a9ed58ced5093e920b77d2a08fb4
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Notifystock.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Adminhtml\Catalog;
+
+class Notifystock extends \Magento\Rss\Controller\Adminhtml\Authenticate
+{
+    /**
+     * Notify stock action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php b/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php
new file mode 100644
index 0000000000000000000000000000000000000000..1fadb7035ffddcf14bb4b67b0fcdb282d92a4003
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Adminhtml/Catalog/Review.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Adminhtml\Catalog;
+
+class Review extends \Magento\Rss\Controller\Adminhtml\Authenticate
+{
+    /**
+     * Review action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Adminhtml/Order.php b/app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
similarity index 85%
rename from app/code/Magento/Rss/Controller/Adminhtml/Order.php
rename to app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
index 0df826dc3a4964956543984e43d797e35a7b685c..149b62f10148aff88630d6b8adf7dafd36d7e508 100644
--- a/app/code/Magento/Rss/Controller/Adminhtml/Order.php
+++ b/app/code/Magento/Rss/Controller/Adminhtml/Order/NewAction.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,19 +22,16 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller\Adminhtml;
+namespace Magento\Rss\Controller\Adminhtml\Order;
 
-/**
- * RSS Controller for Orders feed in Admin
- */
-class Order extends \Magento\Rss\Controller\Adminhtml\Authenticate
+class NewAction extends \Magento\Rss\Controller\Adminhtml\Authenticate
 {
     /**
      * New orders action
      *
      * @return void
      */
-    public function newAction()
+    public function execute()
     {
         $this->getResponse()->setHeader('Content-type', 'text/xml; charset=UTF-8');
         $this->_view->loadLayout(false);
diff --git a/app/code/Magento/Rss/Controller/Catalog.php b/app/code/Magento/Rss/Controller/Catalog.php
index c32a69e5019c0bc60f30bd4d7871860296925107..a3dc1debe8ebbdc2fe0dfd4ea4347fc640eddfc8 100644
--- a/app/code/Magento/Rss/Controller/Catalog.php
+++ b/app/code/Magento/Rss/Controller/Catalog.php
@@ -45,38 +45,6 @@ class Catalog extends \Magento\Framework\App\Action\Action
         parent::__construct($context);
     }
 
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_genericAction('new');
-    }
-
-    /**
-     * @return void
-     */
-    public function specialAction()
-    {
-        $this->_genericAction('special');
-    }
-
-    /**
-     * @return void
-     */
-    public function salesruleAction()
-    {
-        $this->_genericAction('salesrule');
-    }
-
-    /**
-     * @return void
-     */
-    public function categoryAction()
-    {
-        $this->_genericAction('category');
-    }
-
     /**
      * Render or forward to "no route" action if this type of RSS is disabled
      *
diff --git a/app/code/Magento/Rss/Controller/Catalog/Category.php b/app/code/Magento/Rss/Controller/Catalog/Category.php
new file mode 100644
index 0000000000000000000000000000000000000000..28cc586d36f0ef4fca65d6f6170d84f485edecd3
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Catalog/Category.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Catalog;
+
+class Category extends \Magento\Rss\Controller\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_genericAction('category');
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Catalog/NewAction.php b/app/code/Magento/Rss/Controller/Catalog/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba0fbf471b3723742993ba0170d037160464a107
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Catalog/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Catalog;
+
+class NewAction extends \Magento\Rss\Controller\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_genericAction('new');
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Catalog/Salesrule.php b/app/code/Magento/Rss/Controller/Catalog/Salesrule.php
new file mode 100644
index 0000000000000000000000000000000000000000..eeba0161f1922a8904c407ef9bbe386503315764
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Catalog/Salesrule.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Catalog;
+
+class Salesrule extends \Magento\Rss\Controller\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_genericAction('salesrule');
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Catalog/Special.php b/app/code/Magento/Rss/Controller/Catalog/Special.php
new file mode 100644
index 0000000000000000000000000000000000000000..a79f18aabd5dd63eb9f69378ce4f38a01198f6aa
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Catalog/Special.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Catalog;
+
+class Special extends \Magento\Rss\Controller\Catalog
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_genericAction('special');
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Index.php b/app/code/Magento/Rss/Controller/Index.php
index 606e0fb76a685190cccc27b978e90150e5565efd..eb2a045351bd0932dfe71adb1f0a7e9f2e1276e6 100644
--- a/app/code/Magento/Rss/Controller/Index.php
+++ b/app/code/Magento/Rss/Controller/Index.php
@@ -23,8 +23,6 @@
  */
 namespace Magento\Rss\Controller;
 
-use Magento\Framework\App\Action\NotFoundException;
-
 class Index extends \Magento\Framework\App\Action\Action
 {
     /**
@@ -59,64 +57,4 @@ class Index extends \Magento\Framework\App\Action\Action
         $this->_customerSession = $customerSession;
         parent::__construct($context);
     }
-
-    /**
-     * Index action
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function indexAction()
-    {
-        if ($this->_scopeConfig->getValue('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $this->_view->loadLayout();
-            $this->_view->renderLayout();
-        } else {
-            throw new NotFoundException();
-        }
-    }
-
-    /**
-     * Display feed not found message
-     *
-     * @return void
-     */
-    public function nofeedAction()
-    {
-        $this->getResponse()->setHeader(
-            'HTTP/1.1',
-            '404 Not Found'
-        )->setHeader(
-            'Status',
-            '404 File not found'
-        )->setHeader(
-            'Content-Type',
-            'text/plain; charset=UTF-8'
-        )->setBody(
-            __('There was no RSS feed enabled.')
-        );
-    }
-
-    /**
-     * Wishlist rss feed action
-     * Show all public wishlists and private wishlists that belong to current user
-     *
-     * @return void
-     */
-    public function wishlistAction()
-    {
-        if ($this->_scopeConfig->getValue('rss/wishlist/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
-            $wishlist = $this->_wishlistHelper->getWishlist();
-            if ($wishlist && ($wishlist->getVisibility()
-                || $this->_objectManager->get('Magento\Customer\Model\Session')->authenticate($this)
-                && $wishlist->getCustomerId() == $this->_wishlistHelper->getCustomer()->getId())
-            ) {
-                $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=UTF-8');
-                $this->_view->loadLayout(false);
-                $this->_view->renderLayout();
-                return;
-            }
-        }
-        $this->nofeedAction();
-    }
 }
diff --git a/app/code/Magento/Rss/Controller/Index/Index.php b/app/code/Magento/Rss/Controller/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc4f2bf036bbaa99b1dec27f2bdf71f7f60af527
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Index/Index.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Index;
+
+use \Magento\Framework\App\Action\NotFoundException;
+
+class Index extends \Magento\Rss\Controller\Index
+{
+    /**
+     * Index action
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        if ($this->_scopeConfig->getValue('rss/config/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            $this->_view->loadLayout();
+            $this->_view->renderLayout();
+        } else {
+            throw new NotFoundException();
+        }
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Index/Nofeed.php b/app/code/Magento/Rss/Controller/Index/Nofeed.php
new file mode 100644
index 0000000000000000000000000000000000000000..1222cfd72bc81229e67f9273f771c559a5ae125a
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Index/Nofeed.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Index;
+
+class Nofeed extends \Magento\Rss\Controller\Index
+{
+    /**
+     * Display feed not found message
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->getResponse()->setHeader(
+            'HTTP/1.1',
+            '404 Not Found'
+        )->setHeader(
+            'Status',
+            '404 File not found'
+        )->setHeader(
+            'Content-Type',
+            'text/plain; charset=UTF-8'
+        )->setBody(
+            __('There was no RSS feed enabled.')
+        );
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Index/Wishlist.php b/app/code/Magento/Rss/Controller/Index/Wishlist.php
new file mode 100644
index 0000000000000000000000000000000000000000..b501034bea2d9027597ef182a08257e0d0682ae3
--- /dev/null
+++ b/app/code/Magento/Rss/Controller/Index/Wishlist.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Rss\Controller\Index;
+
+class Wishlist extends Nofeed
+{
+    /**
+     * Wishlist rss feed action
+     * Show all public wishlists and private wishlists that belong to current user
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_scopeConfig->getValue('rss/wishlist/active', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)) {
+            $wishlist = $this->_wishlistHelper->getWishlist();
+            if ($wishlist && ($wishlist->getVisibility()
+                || $this->_objectManager->get('Magento\Customer\Model\Session')->authenticate($this)
+                && $wishlist->getCustomerId() == $this->_wishlistHelper->getCustomer()->getId())
+            ) {
+                $this->getResponse()->setHeader('Content-Type', 'text/xml; charset=UTF-8');
+                $this->_view->loadLayout(false);
+                $this->_view->renderLayout();
+                return;
+            }
+        }
+        parent::execute();
+    }
+}
diff --git a/app/code/Magento/Rss/Controller/Order.php b/app/code/Magento/Rss/Controller/Order/Status.php
similarity index 86%
rename from app/code/Magento/Rss/Controller/Order.php
rename to app/code/Magento/Rss/Controller/Order/Status.php
index a0a8b910baac2b30598c693a47806eb87aa496a0..8798ede2110167d479303a74763109e8a33467a6 100644
--- a/app/code/Magento/Rss/Controller/Order.php
+++ b/app/code/Magento/Rss/Controller/Order/Status.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,12 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Rss\Controller;
+namespace Magento\Rss\Controller\Order;
 
-/**
- * RSS Controller for Order feed
- */
-class Order extends \Magento\Framework\App\Action\Action
+class Status extends \Magento\Framework\App\Action\Action
 {
     /**
      * Core registry
@@ -39,8 +37,10 @@ class Order extends \Magento\Framework\App\Action\Action
      * @param \Magento\Framework\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
      */
-    public function __construct(\Magento\Framework\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
         $this->_coreRegistry = $coreRegistry;
         parent::__construct($context);
     }
@@ -50,7 +50,7 @@ class Order extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function statusAction()
+    public function execute()
     {
         $order = $this->_objectManager->get(
             'Magento\Rss\Helper\Order'
diff --git a/app/code/Magento/Rss/Helper/WishlistRss.php b/app/code/Magento/Rss/Helper/WishlistRss.php
index fb3725a16833b9fcb3e3d3352a78a6408dbf22ea..27c465f1dce5d68a174ee5924fbfa68a027f8f0c 100644
--- a/app/code/Magento/Rss/Helper/WishlistRss.php
+++ b/app/code/Magento/Rss/Helper/WishlistRss.php
@@ -46,6 +46,7 @@ class WishlistRss extends \Magento\Wishlist\Helper\Data
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Core\Helper\PostData $postDataHelper
      * @param \Magento\Customer\Helper\View $customerViewHelper
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
      * @param \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
      */
     public function __construct(
@@ -58,6 +59,7 @@ class WishlistRss extends \Magento\Wishlist\Helper\Data
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Core\Helper\PostData $postDataHelper,
         \Magento\Customer\Helper\View $customerViewHelper,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
         \Magento\Customer\Service\V1\Data\CustomerBuilder $customerBuilder
     ) {
         $this->_customerBuilder = $customerBuilder;
@@ -71,7 +73,8 @@ class WishlistRss extends \Magento\Wishlist\Helper\Data
             $wishlistFactory,
             $storeManager,
             $postDataHelper,
-            $customerViewHelper
+            $customerViewHelper,
+            $wishlistProvider
         );
     }
 
diff --git a/app/code/Magento/Rss/etc/adminhtml/routes.xml b/app/code/Magento/Rss/etc/adminhtml/routes.xml
index 481e049916d3820eee99ff1eeb11c47ab7666b7f..99c5397c5c7b1165c4e8c34e4651001035e692e0 100644
--- a/app/code/Magento/Rss/etc/adminhtml/routes.xml
+++ b/app/code/Magento/Rss/etc/adminhtml/routes.xml
@@ -26,7 +26,7 @@
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
     <router id="admin">
         <route id="rss" frontName="rss">
-            <module name="Magento_Rss_Adminhtml" before="Magento_Adminhtml" />
+            <module name="Magento_Rss" before="Magento_Adminhtml" />
         </route>
     </router>
 </config>
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Creditmemo.php b/app/code/Magento/Sales/Block/Adminhtml/Creditmemo.php
index 24d38ab878b5cf657d1e7ac597f9788d7b3b3fd4..2c8511b28c9bc09c0ce539c26df4e8d16f8e0885 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Creditmemo.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Creditmemo.php
@@ -39,6 +39,6 @@ class Creditmemo extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Sales';
         $this->_headerText = __('Credit Memos');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Invoice.php b/app/code/Magento/Sales/Block/Adminhtml/Invoice.php
index 5c63a7a4b05791e92c97d64f685478c88700e063..c7b4c519a820804d5ec4469987bf516c5a371deb 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Invoice.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Invoice.php
@@ -41,7 +41,7 @@ class Invoice extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Sales';
         $this->_headerText = __('Invoices');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order.php b/app/code/Magento/Sales/Block/Adminhtml/Order.php
index ef573cc9fbc30258e9d0847fcc845b2749811511..f63c2f28e7f267ed94c4f7af5049119f1b4e3ed5 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order.php
@@ -43,7 +43,7 @@ class Order extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_addButtonLabel = __('Create New Order');
         parent::_construct();
         if (!$this->_authorization->isAllowed('Magento_Sales::create')) {
-            $this->_removeButton('add');
+            $this->buttonList->remove('add');
         }
     }
 
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Address.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Address.php
index 9ef101f8373497572063671feeacfb3a39f2ae18..bde4ddd7d6d4179bbd34cec1f6fe9d0f775d7eff 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Address.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Address.php
@@ -36,12 +36,12 @@ class Address extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -60,8 +60,8 @@ class Address extends \Magento\Backend\Block\Widget\Form\Container
         $this->_mode = 'address';
         $this->_blockGroup = 'Magento_Sales';
         parent::_construct();
-        $this->_updateButton('save', 'label', __('Save Order Address'));
-        $this->_removeButton('delete');
+        $this->buttonList->update('save', 'label', __('Save Order Address'));
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Create.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Create.php
index 1223bbad94c3110ae40e62b3d3d51cc200c0234e..4b7e8fb468fc6c2bea96ada065e154056700bab6 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Create.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Create.php
@@ -38,12 +38,12 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
     protected $_sessionQuote;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Backend\Model\Session\Quote $sessionQuote
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Backend\Model\Session\Quote $sessionQuote,
         array $data = array()
     ) {
@@ -70,32 +70,32 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
         $storeId = $this->_sessionQuote->getStoreId();
 
 
-        $this->_updateButton('save', 'label', __('Submit Order'));
-        $this->_updateButton('save', 'onclick', 'order.submit()');
-        $this->_updateButton('save', 'class', 'primary');
+        $this->buttonList->update('save', 'label', __('Submit Order'));
+        $this->buttonList->update('save', 'onclick', 'order.submit()');
+        $this->buttonList->update('save', 'class', 'primary');
         // Temporary solution, unset button widget. Will have to wait till jQuery migration is complete
-        $this->_updateButton('save', 'data_attribute', array());
+        $this->buttonList->update('save', 'data_attribute', array());
 
-        $this->_updateButton('save', 'id', 'submit_order_top_button');
+        $this->buttonList->update('save', 'id', 'submit_order_top_button');
         if (is_null($customerId) || !$storeId) {
-            $this->_updateButton('save', 'style', 'display:none');
+            $this->buttonList->update('save', 'style', 'display:none');
         }
 
-        $this->_updateButton('back', 'id', 'back_order_top_button');
-        $this->_updateButton('back', 'onclick', 'setLocation(\'' . $this->getBackUrl() . '\')');
+        $this->buttonList->update('back', 'id', 'back_order_top_button');
+        $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getBackUrl() . '\')');
 
-        $this->_updateButton('reset', 'id', 'reset_order_top_button');
+        $this->buttonList->update('reset', 'id', 'reset_order_top_button');
 
         if (is_null($customerId)) {
-            $this->_updateButton('reset', 'style', 'display:none');
+            $this->buttonList->update('reset', 'style', 'display:none');
         } else {
-            $this->_updateButton('back', 'style', 'display:none');
+            $this->buttonList->update('back', 'style', 'display:none');
         }
 
         $confirm = __('Are you sure you want to cancel this order?');
-        $this->_updateButton('reset', 'label', __('Cancel'));
-        $this->_updateButton('reset', 'class', 'cancel');
-        $this->_updateButton(
+        $this->buttonList->update('reset', 'label', __('Cancel'));
+        $this->buttonList->update('reset', 'class', 'cancel');
+        $this->buttonList->update(
             'reset',
             'onclick',
             'deleteConfirm(\'' . $confirm . '\', \'' . $this->getCancelUrl() . '\')'
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create.php
index c200f6d66c15ca184c9171b1ea52efef350f9eb9..639f84a872fbb453c7ebc4769319c7a9a52a6c70 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/Create.php
@@ -36,12 +36,12 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -62,8 +62,8 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('delete');
-        $this->_removeButton('save');
+        $this->buttonList->remove('delete');
+        $this->buttonList->remove('save');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php
index 6b82b2582da0491f63db8608db65966fbf0515a4..86cd7911522c670e6005938320afb6032652c6b7 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Creditmemo/View.php
@@ -38,12 +38,12 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -64,16 +64,16 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('save');
-        $this->_removeButton('reset');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('save');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
 
         if (!$this->getCreditmemo()) {
             return;
         }
 
         if ($this->getCreditmemo()->canCancel()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'cancel',
                 array(
                     'label' => __('Cancel'),
@@ -97,7 +97,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getCreditmemo()->canRefund()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'refund',
                 array(
                     'label' => __('Refund'),
@@ -108,7 +108,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getCreditmemo()->canVoid()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'void',
                 array(
                     'label' => __('Void'),
@@ -119,7 +119,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getCreditmemo()->getId()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'print',
                 array(
                     'label' => __('Print'),
@@ -243,14 +243,14 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     {
         if ($flag) {
             if ($this->getCreditmemo()->getBackUrl()) {
-                return $this->_updateButton(
+                return $this->buttonList->update(
                     'back',
                     'onclick',
                     'setLocation(\'' . $this->getCreditmemo()->getBackUrl() . '\')'
                 );
             }
 
-            return $this->_updateButton(
+            return $this->buttonList->update(
                 'back',
                 'onclick',
                 'setLocation(\'' . $this->getUrl('sales/creditmemo/') . '\')'
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create.php
index ea8e8f4ff6cd5f64f52db5c35b5d0875cb59b9ca..841bbc8f1df4b75ee11f4c9759acbf1b5b2e1a99 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/Create.php
@@ -36,12 +36,12 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -62,8 +62,8 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('save');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('save');
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php
index ab848a3fa6810d913bdc9c7e7fe24431f2bf6b9c..1a7e9ad5e579348b473a4e5e856ae44082daf38c 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Invoice/View.php
@@ -52,13 +52,13 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     protected $_backendSession;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Backend\Model\Auth\Session $backendSession
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Backend\Model\Auth\Session $backendSession,
         \Magento\Framework\Registry $registry,
         array $data = array()
@@ -82,9 +82,9 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('save');
-        $this->_removeButton('reset');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('save');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
 
         if (!$this->getInvoice()) {
             return;
@@ -94,7 +94,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
             'Magento_Sales::cancel'
         ) && $this->getInvoice()->canCancel() && !$this->_isPaymentReview()
         ) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'cancel',
                 array(
                     'label' => __('Cancel'),
@@ -125,7 +125,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
                 $orderPayment->getAmountPaid() > $orderPayment->getAmountRefunded() ||
                 $orderPayment->canRefund() && !$this->getInvoice()->getIsUsedForRefund()
             ) {
-                $this->_addButton(
+                $this->buttonList->add(
                     'capture',
                     array( // capture?
                         'label' => __('Credit Memo'),
@@ -140,7 +140,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
             'Magento_Sales::capture'
         ) && $this->getInvoice()->canCapture() && !$this->_isPaymentReview()
         ) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'capture',
                 array(
                     'label' => __('Capture'),
@@ -151,7 +151,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getInvoice()->canVoid()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'void',
                 array(
                     'label' => __('Void'),
@@ -162,7 +162,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getInvoice()->getId()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'print',
                 array(
                     'label' => __('Print'),
@@ -307,13 +307,13 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     {
         if ($flag) {
             if ($this->getInvoice()->getBackUrl()) {
-                return $this->_updateButton(
+                return $this->buttonList->update(
                     'back',
                     'onclick',
                     'setLocation(\'' . $this->getInvoice()->getBackUrl() . '\')'
                 );
             }
-            return $this->_updateButton('back', 'onclick', 'setLocation(\'' . $this->getUrl('sales/invoice/') . '\')');
+            return $this->buttonList->update('back', 'onclick', 'setLocation(\'' . $this->getUrl('sales/invoice/') . '\')');
         }
         return $this;
     }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Status.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Status.php
index 165de4f5b4cbb06662ddd77c85721425a12f68dc..92b6df3297a1c8d9ab0d8690fec12c5b847ca6a5 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Status.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Status.php
@@ -40,7 +40,7 @@ class Status extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_order_status';
         $this->_headerText = __('Order Statuses');
         $this->_addButtonLabel = __('Create New Status');
-        $this->_addButton(
+        $this->buttonList->add(
             'assign',
             array(
                 'label' => __('Assign Status to State'),
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Status/Assign.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Status/Assign.php
index 98f24f3724cd303345c1681ee32b60fbc0feeb4e..75a8fea4ac8e3f982cdc5ef48085b4e4334cb287 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Status/Assign.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Status/Assign.php
@@ -36,8 +36,8 @@ class Assign extends \Magento\Backend\Block\Widget\Form\Container
         $this->_mode = 'assign';
         $this->_blockGroup = 'Magento_Sales';
         parent::_construct();
-        $this->_updateButton('save', 'label', __('Save Status Assignment'));
-        $this->_removeButton('delete');
+        $this->buttonList->update('save', 'label', __('Save Status Assignment'));
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/Status/NewStatus.php b/app/code/Magento/Sales/Block/Adminhtml/Order/Status/NewStatus.php
index 371d34d0dca6af2f3705db54fc687c8bd75e424c..f9713be2d8396fe3a3f3b8031401b12fda70fcbf 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/Status/NewStatus.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/Status/NewStatus.php
@@ -38,8 +38,8 @@ class NewStatus extends \Magento\Backend\Block\Widget\Form\Container
         $this->_mode = 'newStatus';
 
         parent::_construct();
-        $this->_updateButton('save', 'label', __('Save Status'));
-        $this->_removeButton('delete');
+        $this->buttonList->update('save', 'label', __('Save Status'));
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Order/View.php b/app/code/Magento/Sales/Block/Adminhtml/Order/View.php
index 4c7212e31467273d8c5b2d7982053c5cf9803847..494e7b5527a4765d3bb4069097adf5523ff0ce9b 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Order/View.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Order/View.php
@@ -59,14 +59,14 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     protected $_reorderHelper;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Sales\Model\Config $salesConfig
      * @param \Magento\Sales\Helper\Reorder $reorderHelper
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Sales\Model\Config $salesConfig,
         \Magento\Sales\Helper\Reorder $reorderHelper,
@@ -91,9 +91,9 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('delete');
-        $this->_removeButton('reset');
-        $this->_removeButton('save');
+        $this->buttonList->remove('delete');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('save');
         $this->setId('sales_order_view');
         $order = $this->getOrder();
 
@@ -106,7 +106,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
                 . $this->getEditMessage($order) . '\', url: \'' . $this->getEditUrl()
                 . '\'}).orderEditDialog(\'showDialog\');';
 
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_edit',
                 array(
                     'label' => __('Edit'),
@@ -121,7 +121,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         if ($this->_isAllowedAction('Magento_Sales::cancel') && $order->canCancel()) {
             $message = __('Are you sure you want to cancel this order?');
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_cancel',
                 array(
                     'label' => __('Cancel'),
@@ -152,7 +152,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
             if ($order->getPayment()->getMethodInstance()->isGateway()) {
                 $onClick = "confirmSetLocation('{$message}', '{$this->getCreditmemoUrl()}')";
             }
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_creditmemo',
                 array('label' => __('Credit Memo'), 'onclick' => $onClick, 'class' => 'credit-memo')
             );
@@ -171,7 +171,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->_isAllowedAction('Magento_Sales::hold') && $order->canHold()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_hold',
                 array(
                     'label' => __('Hold'),
@@ -182,7 +182,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->_isAllowedAction('Magento_Sales::unhold') && $order->canUnhold()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_unhold',
                 array(
                     'label' => __('Unhold'),
@@ -195,7 +195,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         if ($this->_isAllowedAction('Magento_Sales::review_payment')) {
             if ($order->canReviewPayment()) {
                 $message = __('Are you sure you want to accept this payment?');
-                $this->_addButton(
+                $this->buttonList->add(
                     'accept_payment',
                     array(
                         'label' => __('Accept Payment'),
@@ -203,7 +203,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
                     )
                 );
                 $message = __('Are you sure you want to deny this payment?');
-                $this->_addButton(
+                $this->buttonList->add(
                     'deny_payment',
                     array(
                         'label' => __('Deny Payment'),
@@ -212,7 +212,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
                 );
             }
             if ($order->canFetchPaymentReviewUpdate()) {
-                $this->_addButton(
+                $this->buttonList->add(
                     'get_review_payment_update',
                     array(
                         'label' => __('Get Payment Update'),
@@ -224,7 +224,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         if ($this->_isAllowedAction('Magento_Sales::invoice') && $order->canInvoice()) {
             $_label = $order->getForcedShipmentWithInvoice() ? __('Invoice and Ship') : __('Invoice');
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_invoice',
                 array(
                     'label' => $_label,
@@ -238,7 +238,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
             'Magento_Sales::ship'
         ) && $order->canShip() && !$order->getForcedShipmentWithInvoice()
         ) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_ship',
                 array(
                     'label' => __('Ship'),
@@ -254,7 +254,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
             $order->getStore()
         ) && $order->canReorderIgnoreSalable()
         ) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'order_reorder',
                 array(
                     'label' => __('Reorder'),
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Shipment.php b/app/code/Magento/Sales/Block/Adminhtml/Shipment.php
index 8f04f05fc584590c151d678e7d89ffe674161090..d6fcf202c6089e1e0891d7517c9470dea111c7c4 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Shipment.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Shipment.php
@@ -41,6 +41,6 @@ class Shipment extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Sales';
         $this->_headerText = __('Shipments');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Transactions.php b/app/code/Magento/Sales/Block/Adminhtml/Transactions.php
index 50495116b6bd3f6d65b17f6e4912244e5e8fe3dd..7090d420eedff2cfa71b83d08d782a8ed2509249 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Transactions.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Transactions.php
@@ -41,6 +41,6 @@ class Transactions extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_blockGroup = 'Magento_Sales';
         $this->_headerText = __('Transactions');
         parent::_construct();
-        $this->_removeButton('add');
+        $this->buttonList->remove('add');
     }
 }
diff --git a/app/code/Magento/Sales/Block/Adminhtml/Transactions/Detail.php b/app/code/Magento/Sales/Block/Adminhtml/Transactions/Detail.php
index 0ce2d8a23b91807c560ab3be863a9bb90851bbc4..da13149eb1387bb29d312ba4d7a620c7bd010a56 100644
--- a/app/code/Magento/Sales/Block/Adminhtml/Transactions/Detail.php
+++ b/app/code/Magento/Sales/Block/Adminhtml/Transactions/Detail.php
@@ -45,12 +45,12 @@ class Detail extends \Magento\Backend\Block\Widget\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -73,7 +73,7 @@ class Detail extends \Magento\Backend\Block\Widget\Container
         }
 
         $backUrl = $this->_txn->getOrderUrl() ? $this->_txn->getOrderUrl() : $this->getUrl('sales/*/');
-        $this->_addButton(
+        $this->buttonList->add(
             'back',
             array('label' => __('Back'), 'onclick' => "setLocation('{$backUrl}')", 'class' => 'back')
         );
@@ -83,7 +83,7 @@ class Detail extends \Magento\Backend\Block\Widget\Container
         ) && $this->_txn->getOrderPaymentObject()->getMethodInstance()->canFetchTransactionInfo()
         ) {
             $fetchUrl = $this->getUrl('sales/*/fetch', array('_current' => true));
-            $this->_addButton(
+            $this->buttonList->add(
                 'fetch',
                 array('label' => __('Fetch'), 'onclick' => "setLocation('{$fetchUrl}')", 'class' => 'button')
             );
diff --git a/app/code/Magento/Sales/Controller/AbstractController.php b/app/code/Magento/Sales/Controller/AbstractController.php
deleted file mode 100644
index fb65d0748a7b94156bb57a95b72d05632fe38054..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/AbstractController.php
+++ /dev/null
@@ -1,302 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller;
-
-/**
- * Sales Controller
- */
-abstract class AbstractController extends \Magento\Framework\App\Action\Action
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
-    /**
-     * Check order view availability
-     *
-     * @param   \Magento\Sales\Model\Order $order
-     * @return  bool
-     */
-    protected function _canViewOrder($order)
-    {
-        $customerId = $this->_objectManager->get('Magento\Customer\Model\Session')->getCustomerId();
-        $availableStatuses = $this->_objectManager->get('Magento\Sales\Model\Order\Config')
-            ->getVisibleOnFrontStatuses();
-        if ($order->getId()
-            && $order->getCustomerId()
-            && $order->getCustomerId() == $customerId
-            && in_array($order->getStatus(), $availableStatuses, true)
-        ) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Init layout, messages and set active block for customer
-     *
-     * @return void
-     */
-    protected function _viewAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
-        if ($navigationBlock) {
-            $navigationBlock->setActive('sales/order/history');
-        }
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Try to load valid order by order_id and register it
-     *
-     * @param int $orderId
-     * @return bool
-     */
-    protected function _loadValidOrder($orderId = null)
-    {
-        if (null === $orderId) {
-            $orderId = (int)$this->getRequest()->getParam('order_id');
-        }
-        if (!$orderId) {
-            $this->_forward('noroute');
-            return false;
-        }
-
-        $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-
-        if ($this->_canViewOrder($order)) {
-            $this->_coreRegistry->register('current_order', $order);
-            return true;
-        } else {
-            $this->_redirect('*/*/history');
-        }
-        return false;
-    }
-
-    /**
-     * Order view page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Invoice page
-     *
-     * @return void
-     */
-    public function invoiceAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Shipment page
-     *
-     * @return void
-     */
-    public function shipmentAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Creditmemo page
-     *
-     * @return void
-     */
-    public function creditmemoAction()
-    {
-        $this->_viewAction();
-    }
-
-    /**
-     * Action for reorder
-     *
-     * @return void
-     */
-    public function reorderAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-        $order = $this->_coreRegistry->registry('current_order');
-
-        /* @var $cart \Magento\Checkout\Model\Cart */
-        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
-        $items = $order->getItemsCollection();
-        foreach ($items as $item) {
-            try {
-                $cart->addOrderItem($item);
-            } catch (\Magento\Framework\Model\Exception $e) {
-                if ($this->_objectManager->get('Magento\Checkout\Model\Session')->getUseNotice(true)) {
-                    $this->messageManager->addNotice($e->getMessage());
-                } else {
-                    $this->messageManager->addError($e->getMessage());
-                }
-                $this->_redirect('*/*/history');
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('We cannot add this item to your shopping cart.'));
-                $this->_redirect('checkout/cart');
-            }
-        }
-
-        $cart->save();
-        $this->_redirect('checkout/cart');
-    }
-
-    /**
-     * Print Order Action
-     *
-     * @return void
-     */
-    public function printAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-        $this->_view->loadLayout('print');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Print Invoice Action
-     *
-     * @return void
-     */
-    public function printInvoiceAction()
-    {
-        $invoiceId = (int)$this->getRequest()->getParam('invoice_id');
-        if ($invoiceId) {
-            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
-            $order = $invoice->getOrder();
-        } else {
-            $orderId = (int)$this->getRequest()->getParam('order_id');
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-        }
-
-        if ($this->_canViewOrder($order)) {
-            $this->_coreRegistry->register('current_order', $order);
-            if (isset($invoice)) {
-                $this->_coreRegistry->register('current_invoice', $invoice);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-                $this->_redirect('*/*/history');
-            } else {
-                $this->_redirect('sales/guest/form');
-            }
-        }
-    }
-
-    /**
-     * Print Shipment Action
-     *
-     * @return void
-     */
-    public function printShipmentAction()
-    {
-        $shipmentId = (int)$this->getRequest()->getParam('shipment_id');
-        if ($shipmentId) {
-            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
-            $order = $shipment->getOrder();
-        } else {
-            $orderId = (int)$this->getRequest()->getParam('order_id');
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-        }
-        if ($this->_canViewOrder($order)) {
-            $this->_coreRegistry->register('current_order', $order);
-            if (isset($shipment)) {
-                $this->_coreRegistry->register('current_shipment', $shipment);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-                $this->_redirect('*/*/history');
-            } else {
-                $this->_redirect('sales/guest/form');
-            }
-        }
-    }
-
-    /**
-     * Print Creditmemo Action
-     *
-     * @return void
-     */
-    public function printCreditmemoAction()
-    {
-        $creditmemoId = (int)$this->getRequest()->getParam('creditmemo_id');
-        if ($creditmemoId) {
-            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
-            $order = $creditmemo->getOrder();
-        } else {
-            $orderId = (int)$this->getRequest()->getParam('order_id');
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-        }
-
-        if ($this->_canViewOrder($order)) {
-            $this->_coreRegistry->register('current_order', $order);
-            if (isset($creditmemo)) {
-                $this->_coreRegistry->register('current_creditmemo', $creditmemo);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-                $this->_redirect('*/*/history');
-            } else {
-                $this->_redirect('sales/guest/form');
-            }
-        }
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/Creditmemo.php b/app/code/Magento/Sales/Controller/AbstractController/Creditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfef76e1f245732e1c6376ddeae3e30d9325b72d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/Creditmemo.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+abstract class Creditmemo extends \Magento\Sales\Controller\AbstractController\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/Invoice.php b/app/code/Magento/Sales/Controller/AbstractController/Invoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..6127294f7de5527ee3cc161247ce5c6273085591
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/Invoice.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+abstract class Invoice extends \Magento\Sales\Controller\AbstractController\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/OrderLoader.php b/app/code/Magento/Sales/Controller/AbstractController/OrderLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..df376de8349351ff2fbd30bc73487f4ff9101063
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/OrderLoader.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\ResponseInterface;
+use Magento\Framework\Registry;
+
+class OrderLoader implements OrderLoaderInterface
+{
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @var OrderViewAuthorizationInterface
+     */
+    protected $orderAuthorization;
+
+    /**
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $url;
+
+    /**
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param OrderViewAuthorizationInterface $orderAuthorization
+     * @param Registry $registry
+     * @param \Magento\Framework\UrlInterface $url
+     */
+    public function __construct(
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        OrderViewAuthorizationInterface $orderAuthorization,
+        Registry $registry,
+        \Magento\Framework\UrlInterface $url
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->orderAuthorization = $orderAuthorization;
+        $this->registry = $registry;
+        $this->url = $url;
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param ResponseInterface $response
+     * @return bool
+     */
+    public function load(RequestInterface $request, ResponseInterface $response)
+    {
+        $orderId = (int)$request->getParam('order_id');
+        if (!$orderId) {
+            $request->initForward();
+            $request->setActionName('noroute');
+            $request->setDispatched(false);
+            return false;
+        }
+
+        $order = $this->orderFactory->create()->load($orderId);
+
+        if ($this->orderAuthorization->canView($order)) {
+            $this->registry->register('current_order', $order);
+            return true;
+        }
+        $response->setRedirect($this->url->getUrl('*/*/history'));
+        return false;
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/OrderLoaderInterface.php b/app/code/Magento/Sales/Controller/AbstractController/OrderLoaderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..60ee8acde4b81d597950aa9bec6161bfe7db9112
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/OrderLoaderInterface.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\ResponseInterface;
+
+interface OrderLoaderInterface
+{
+    /**
+     * Load order
+     *
+     * @param RequestInterface $request
+     * @param ResponseInterface $response
+     * @return \Magento\Sales\Model\Order
+     */
+    public function load(RequestInterface $request, ResponseInterface $response);
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorization.php b/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorization.php
new file mode 100644
index 0000000000000000000000000000000000000000..8695125b96952aad973d86f22cdb281f13a2f3e9
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorization.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Sales\Controller\AbstractController;
+
+
+class OrderViewAuthorization implements OrderViewAuthorizationInterface
+{
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Sales\Model\Order\Config
+     */
+    protected $orderConfig;
+
+    /**
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Sales\Model\Order\Config $orderConfig
+     */
+    public function __construct(
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Sales\Model\Order\Config $orderConfig
+    ) {
+        $this->customerSession = $customerSession;
+        $this->orderConfig = $orderConfig;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function canView(\Magento\Sales\Model\Order $order)
+    {
+        $customerId = $this->customerSession->getCustomerId();
+        $availableStatuses = $this->orderConfig->getVisibleOnFrontStatuses();
+        if ($order->getId()
+            && $order->getCustomerId()
+            && $order->getCustomerId() == $customerId
+            && in_array($order->getStatus(), $availableStatuses, true)
+        ) {
+            return true;
+        }
+        return false;
+
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorizationInterface.php b/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorizationInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..86c47b9fe53998ae43afc2246a7ce63b28590917
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/OrderViewAuthorizationInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+interface OrderViewAuthorizationInterface
+{
+    /**
+     * Check if order can be viewed by user
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return bool
+     */
+    public function canView(\Magento\Sales\Model\Order $order);
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/PrintAction.php b/app/code/Magento/Sales/Controller/AbstractController/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..02563be3587b4087754c2798004fac9641bc4b6e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/PrintAction.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\Action\Context;
+
+abstract class PrintAction extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\AbstractController\OrderLoaderInterface
+     */
+    protected $orderLoader;
+
+    /**
+     * @param Context $context
+     * @param OrderLoaderInterface $orderLoader
+     */
+    public function __construct(Context $context, OrderLoaderInterface $orderLoader)
+    {
+        $this->orderLoader = $orderLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * Print Order Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+        $this->_view->loadLayout('print');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/PrintCreditmemo.php b/app/code/Magento/Sales/Controller/AbstractController/PrintCreditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..93163291c275c873dd7f658049354e061d5f1740
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/PrintCreditmemo.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\Action\Context;
+
+abstract class PrintCreditmemo extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var OrderViewAuthorizationInterface
+     */
+    protected $orderAuthorization;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorizationInterface $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorizationInterface $orderAuthorization,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->orderAuthorization = $orderAuthorization;
+        $this->_coreRegistry = $registry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Print Creditmemo Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $creditmemoId = (int)$this->getRequest()->getParam('creditmemo_id');
+        if ($creditmemoId) {
+            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
+            $order = $creditmemo->getOrder();
+        } else {
+            $orderId = (int)$this->getRequest()->getParam('order_id');
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+        }
+
+        if ($this->orderAuthorization->canView($order)) {
+            $this->_coreRegistry->register('current_order', $order);
+            if (isset($creditmemo)) {
+                $this->_coreRegistry->register('current_creditmemo', $creditmemo);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+                $this->_redirect('*/*/history');
+            } else {
+                $this->_redirect('sales/guest/form');
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/PrintInvoice.php b/app/code/Magento/Sales/Controller/AbstractController/PrintInvoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..1f4ca857821c91ce235f2c9f54bba4534a6a1bb0
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/PrintInvoice.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\Action\Context;
+
+abstract class PrintInvoice extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var OrderViewAuthorizationInterface
+     */
+    protected $orderAuthorization;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorizationInterface $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorizationInterface $orderAuthorization,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->orderAuthorization = $orderAuthorization;
+        $this->_coreRegistry = $registry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Print Invoice Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $invoiceId = (int)$this->getRequest()->getParam('invoice_id');
+        if ($invoiceId) {
+            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
+            $order = $invoice->getOrder();
+        } else {
+            $orderId = (int)$this->getRequest()->getParam('order_id');
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+        }
+
+        if ($this->orderAuthorization->canView($order)) {
+            $this->_coreRegistry->register('current_order', $order);
+            if (isset($invoice)) {
+                $this->_coreRegistry->register('current_invoice', $invoice);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+                $this->_redirect('*/*/history');
+            } else {
+                $this->_redirect('sales/guest/form');
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/PrintShipment.php b/app/code/Magento/Sales/Controller/AbstractController/PrintShipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc8a50f9118934b1360cc8827eb0541313d27f28
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/PrintShipment.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use \Magento\Framework\App\Action\Context;
+
+abstract class PrintShipment extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var OrderViewAuthorizationInterface
+     */
+    protected $orderAuthorization;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorizationInterface $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorizationInterface $orderAuthorization,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->orderAuthorization = $orderAuthorization;
+        $this->_coreRegistry = $registry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Print Shipment Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $shipmentId = (int)$this->getRequest()->getParam('shipment_id');
+        if ($shipmentId) {
+            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
+            $order = $shipment->getOrder();
+        } else {
+            $orderId = (int)$this->getRequest()->getParam('order_id');
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+        }
+        if ($this->orderAuthorization->canView($order)) {
+            $this->_coreRegistry->register('current_order', $order);
+            if (isset($shipment)) {
+                $this->_coreRegistry->register('current_shipment', $shipment);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+                $this->_redirect('*/*/history');
+            } else {
+                $this->_redirect('sales/guest/form');
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/Reorder.php b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..15fb8259c4909440f564bf9d668013d125eaed3d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/Reorder.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use \Magento\Framework\App\Action;
+
+abstract class Reorder extends Action\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\AbstractController\OrderLoaderInterface
+     */
+    protected $orderLoader;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @param Action\Context $context
+     * @param OrderLoaderInterface $orderLoader
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        Action\Context $context,
+        OrderLoaderInterface $orderLoader,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->orderLoader = $orderLoader;
+        $this->_coreRegistry = $registry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Action for reorder
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+        $order = $this->_coreRegistry->registry('current_order');
+
+        /* @var $cart \Magento\Checkout\Model\Cart */
+        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
+        $items = $order->getItemsCollection();
+        foreach ($items as $item) {
+            try {
+                $cart->addOrderItem($item);
+            } catch (\Magento\Framework\Model\Exception $e) {
+                if ($this->_objectManager->get('Magento\Checkout\Model\Session')->getUseNotice(true)) {
+                    $this->messageManager->addNotice($e->getMessage());
+                } else {
+                    $this->messageManager->addError($e->getMessage());
+                }
+                $this->_redirect('*/*/history');
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('We cannot add this item to your shopping cart.'));
+                $this->_redirect('checkout/cart');
+            }
+        }
+
+        $cart->save();
+        $this->_redirect('checkout/cart');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/Shipment.php b/app/code/Magento/Sales/Controller/AbstractController/Shipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5254108364f66f7350d8dff7feddd1e33561518
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/Shipment.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+abstract class Shipment extends \Magento\Sales\Controller\AbstractController\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/AbstractController/View.php b/app/code/Magento/Sales/Controller/AbstractController/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab74b852a14623a9eaa7426e30e6866c13d19250
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/AbstractController/View.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\AbstractController;
+
+use Magento\Framework\App\Action;
+
+abstract class View extends Action\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\AbstractController\OrderLoaderInterface
+     */
+    protected $orderLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param OrderLoaderInterface $orderLoader
+     */
+    public function __construct(Action\Context $context, OrderLoaderInterface $orderLoader)
+    {
+        $this->orderLoader = $orderLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * Order view page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $navigationBlock = $this->_view->getLayout()->getBlock('customer_account_navigation');
+        if ($navigationBlock) {
+            $navigationBlock->setActive('sales/order/history');
+        }
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo.php
deleted file mode 100644
index eaa071486912073d917e25748f9d36b4fa3b8b24..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo.php
+++ /dev/null
@@ -1,205 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
-
-use Magento\Framework\App\ResponseInterface;
-
-/**
- * Adminhtml sales orders controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class AbstractCreditmemo extends \Magento\Backend\App\Action
-{
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-    ) {
-        $this->_fileFactory = $fileFactory;
-        parent::__construct($context);
-    }
-
-    /**
-     * Init layout, menu and breadcrumb
-     *
-     * @return \Magento\Sales\Controller\Adminhtml\Creditmemo
-     */
-    protected function _initAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Sales::sales_creditmemo'
-        )->_addBreadcrumb(
-            __('Sales'),
-            __('Sales')
-        )->_addBreadcrumb(
-            __('Credit Memos'),
-            __('Credit Memos')
-        );
-        return $this;
-    }
-
-    /**
-     * Creditmemos grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Creditmemo information page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        if ($creditmemoId = $this->getRequest()->getParam('creditmemo_id')) {
-            $this->_forward('view', 'order_creditmemo', null, array('come_from' => 'sales_creditmemo'));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Notify user
-     *
-     * @return void
-     */
-    public function emailAction()
-    {
-        $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
-        if ($creditmemoId) {
-            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
-            if ($creditmemo) {
-                $creditmemo->sendEmail();
-                $historyItem = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
-                )->getUnnotifiedForInstance(
-                    $creditmemo,
-                    \Magento\Sales\Model\Order\Creditmemo::HISTORY_ENTITY_NAME
-                );
-                if ($historyItem) {
-                    $historyItem->setIsCustomerNotified(1);
-                    $historyItem->save();
-                }
-
-                $this->messageManager->addSuccess(__('We sent the message.'));
-                $this->_redirect('sales/order_creditmemo/view', array('creditmemo_id' => $creditmemoId));
-            }
-        }
-    }
-
-    /**
-     * @return ResponseInterface|void
-     */
-    public function pdfcreditmemosAction()
-    {
-        $creditmemosIds = $this->getRequest()->getPost('creditmemo_ids');
-        if (!empty($creditmemosIds)) {
-            $invoices = $this->_objectManager->create(
-                'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
-            )->addAttributeToSelect(
-                '*'
-            )->addAttributeToFilter(
-                'entity_id',
-                array('in' => $creditmemosIds)
-            )->load();
-            if (!isset($pdf)) {
-                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Creditmemo')->getPdf($invoices);
-            } else {
-                $pages = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Creditmemo')->getPdf($invoices);
-                $pdf->pages = array_merge($pdf->pages, $pages->pages);
-            }
-            $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
-
-            return $this->_fileFactory->create(
-                'creditmemo' . $date . '.pdf',
-                $pdf->render(),
-                \Magento\Framework\App\Filesystem::VAR_DIR,
-                'application/pdf'
-            );
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * @return ResponseInterface|void
-     */
-    public function printAction()
-    {
-        /** @see \Magento\Sales\Controller\Adminhtml\Order\Invoice */
-        $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
-        if ($creditmemoId) {
-            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
-            if ($creditmemo) {
-                $pdf = $this->_objectManager->create(
-                    'Magento\Sales\Model\Order\Pdf\Creditmemo'
-                )->getPdf(
-                    array($creditmemo)
-                );
-                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
-                return $this->_fileFactory->create(
-                    'creditmemo' . $date . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            }
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
-    }
-
-    /**
-     * Creditmemo grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..f33ac4e591ad5ac7f05652b65a69f53e0d831945
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Email.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+class Email extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Notify user
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
+        if ($creditmemoId) {
+            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
+            if ($creditmemo) {
+                $creditmemo->sendEmail();
+                $historyItem = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
+                )->getUnnotifiedForInstance(
+                    $creditmemo,
+                    \Magento\Sales\Model\Order\Creditmemo::HISTORY_ENTITY_NAME
+                );
+                if ($historyItem) {
+                    $historyItem->setIsCustomerNotified(1);
+                    $historyItem->save();
+                }
+
+                $this->messageManager->addSuccess(__('We sent the message.'));
+                $this->_redirect('sales/order_creditmemo/view', array('creditmemo_id' => $creditmemoId));
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..c445ef5eaa046fbb0ff27249a71867c316d25dac
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Grid.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+class Grid extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Creditmemo grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..54b59cc428a8777f4a44c09b6056cc8ec8186049
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Index.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Init layout, menu and breadcrumb
+     *
+     * @return $this
+     */
+    protected function _initAction()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Sales::sales_creditmemo'
+        )->_addBreadcrumb(
+            __('Sales'),
+            __('Sales')
+        )->_addBreadcrumb(
+            __('Credit Memos'),
+            __('Credit Memos')
+        );
+        return $this;
+    }
+
+    /**
+     * Creditmemos grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Pdfcreditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Pdfcreditmemos.php
new file mode 100644
index 0000000000000000000000000000000000000000..590e3e815565491f43522714b3c12bf38a2800ad
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/Pdfcreditmemos.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class Pdfcreditmemos extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $creditmemosIds = $this->getRequest()->getPost('creditmemo_ids');
+        if (!empty($creditmemosIds)) {
+            $invoices = $this->_objectManager->create(
+                'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
+            )->addAttributeToSelect(
+                '*'
+            )->addAttributeToFilter(
+                'entity_id',
+                array('in' => $creditmemosIds)
+            )->load();
+            if (!isset($pdf)) {
+                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Creditmemo')->getPdf($invoices);
+            } else {
+                $pages = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Creditmemo')->getPdf($invoices);
+                $pdf->pages = array_merge($pdf->pages, $pages->pages);
+            }
+            $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
+
+            return $this->_fileFactory->create(
+                'creditmemo' . $date . '.pdf',
+                $pdf->render(),
+                \Magento\Framework\App\Filesystem::VAR_DIR,
+                'application/pdf'
+            );
+        }
+        return $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa8e77a8031fa9bb3967774dea2b9a77514b8f77
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/PrintAction.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class PrintAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        /** @see \Magento\Sales\Controller\Adminhtml\Order\Invoice */
+        $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
+        if ($creditmemoId) {
+            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
+            if ($creditmemo) {
+                $pdf = $this->_objectManager->create(
+                    'Magento\Sales\Model\Order\Pdf\Creditmemo'
+                )->getPdf(
+                    array($creditmemo)
+                );
+                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
+                return $this->_fileFactory->create(
+                    'creditmemo' . $date . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            }
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd24820da8a20e0960e587484951df88163d87d1
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/AbstractCreditmemo/View.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo;
+
+class View extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Creditmemo information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($creditmemoId = $this->getRequest()->getParam('creditmemo_id')) {
+            $this->_forward('view', 'order_creditmemo', null, array('come_from' => 'sales_creditmemo'));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..620f51aa98de5cd1d9fa28defb3454bc9bf2b8b2
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Email.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class Email extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Email
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportCsv.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..7de7150e602a39f3bf9eff385cd086cf9f51c3ca
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportCsv.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCsv extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Export credit memo grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'creditmemos.csv';
+        $grid = $grid = $this->_view->getLayout()->getChildBlock('sales.creditmemo.grid', 'grid.export');
+        $csvFile = $grid->getCsvFile();
+        return $this->_fileFactory->create($fileName, $csvFile, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportExcel.php
similarity index 60%
rename from app/code/Magento/Sales/Controller/Adminhtml/Creditmemo.php
rename to app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportExcel.php
index fa98d677a89bc88b5610507010e602660038bd5f..0d50acc30679abbd57ecc410e6184488f30e874d 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/ExportExcel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,29 +22,35 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml;
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
 
-use Magento\Framework\App\ResponseInterface;
+use \Magento\Framework\App\ResponseInterface;
 
-/**
- * Adminhtml sales orders controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo
+class ExportExcel extends \Magento\Backend\App\Action
 {
     /**
-     * Export credit memo grid to CSV format
-     *
-     * @return ResponseInterface
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
      */
-    public function exportCsvAction()
+    protected function _isAllowed()
     {
-        $this->_view->loadLayout(false);
-        $fileName = 'creditmemos.csv';
-        $grid = $grid = $this->_view->getLayout()->getChildBlock('sales.creditmemo.grid', 'grid.export');
-        $csvFile = $grid->getCsvFile();
-        return $this->_fileFactory->create($fileName, $csvFile, \Magento\Framework\App\Filesystem::VAR_DIR);
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
     }
 
     /**
@@ -51,7 +58,7 @@ class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\Abstract
      *
      * @return ResponseInterface
      */
-    public function exportExcelAction()
+    public function execute()
     {
         $this->_view->loadLayout(false);
         $fileName = 'creditmemos.xml';
@@ -62,15 +69,4 @@ class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\Abstract
             \Magento\Framework\App\Filesystem::VAR_DIR
         );
     }
-
-    /**
-     * Index page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Credit Memos'));
-        parent::indexAction();
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..1731818face23a2ed2f79ec8e6eb85b9cbde6b89
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Grid
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..13cd89e79d81f4d86f9b16a63273abb4d191ec36
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Index
+{
+    /**
+     * Index page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Credit Memos'));
+        parent::execute();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Pdfcreditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Pdfcreditmemos.php
new file mode 100644
index 0000000000000000000000000000000000000000..e455f23f3af34a9a1fc13d15a26fa158bc9c83b7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/Pdfcreditmemos.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class Pdfcreditmemos extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Pdfcreditmemos
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b21d6580498c941bbaae9b4a6a79caa4b01c55b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/PrintAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\PrintAction
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..206a6c1aceb4233556f02efd4a329aa10425363f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Creditmemo/View.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Creditmemo;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice.php
deleted file mode 100644
index d62aa0478811bf93f410ebfd4b3aca4fd2a1fd45..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice.php
+++ /dev/null
@@ -1,202 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller\Adminhtml\Invoice;
-
-use Magento\Framework\App\ResponseInterface;
-
-/**
- * Adminhtml sales orders controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class AbstractInvoice extends \Magento\Backend\App\Action
-{
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-    ) {
-        $this->_fileFactory = $fileFactory;
-        parent::__construct($context);
-    }
-
-    /**
-     * Init layout, menu and breadcrumb
-     *
-     * @return \Magento\Sales\Controller\Adminhtml\Invoice
-     */
-    protected function _initAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Sales::sales_invoice'
-        )->_addBreadcrumb(
-            __('Sales'),
-            __('Sales')
-        )->_addBreadcrumb(
-            __('Invoices'),
-            __('Invoices')
-        );
-        return $this;
-    }
-
-    /**
-     * Order grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Invoices grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Invoices'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Invoice information page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        if ($invoiceId = $this->getRequest()->getParam('invoice_id')) {
-            $this->_forward('view', 'order_invoice', null, array('come_from' => 'invoice'));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Notify user
-     *
-     * @return void
-     */
-    public function emailAction()
-    {
-        if ($invoiceId = $this->getRequest()->getParam('invoice_id')) {
-            if ($invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId)) {
-                $invoice->sendEmail();
-                $historyItem = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
-                )->getUnnotifiedForInstance(
-                    $invoice,
-                    \Magento\Sales\Model\Order\Invoice::HISTORY_ENTITY_NAME
-                );
-                if ($historyItem) {
-                    $historyItem->setIsCustomerNotified(1);
-                    $historyItem->save();
-                }
-                $this->messageManager->addSuccess(__('We sent the message.'));
-                $this->_redirect(
-                    'sales/invoice/view',
-                    array('order_id' => $invoice->getOrder()->getId(), 'invoice_id' => $invoiceId)
-                );
-            }
-        }
-    }
-
-    /**
-     * @return ResponseInterface|void
-     */
-    public function printAction()
-    {
-        $invoiceId = $this->getRequest()->getParam('invoice_id');
-        if ($invoiceId) {
-            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
-            if ($invoice) {
-                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf(array($invoice));
-                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
-                return $this->_fileFactory->create(
-                    'invoice' . $date . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            }
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * @return ResponseInterface|void
-     */
-    public function pdfinvoicesAction()
-    {
-        $invoicesIds = $this->getRequest()->getPost('invoice_ids');
-        if (!empty($invoicesIds)) {
-            $invoices = $this->_objectManager->create(
-                'Magento\Sales\Model\Resource\Order\Invoice\Collection'
-            )->addAttributeToSelect(
-                '*'
-            )->addAttributeToFilter(
-                'entity_id',
-                array('in' => $invoicesIds)
-            )->load();
-            if (!isset($pdf)) {
-                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf($invoices);
-            } else {
-                $pages = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf($invoices);
-                $pdf->pages = array_merge($pdf->pages, $pages->pages);
-            }
-            $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
-
-            return $this->_fileFactory->create(
-                'invoice' . $date . '.pdf',
-                $pdf->render(),
-                \Magento\Framework\App\Filesystem::VAR_DIR,
-                'application/pdf'
-            );
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd60dec7ec33d1ef495ab3134101dc8d23a5a29f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Email.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+abstract class Email extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Notify user
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($invoiceId = $this->getRequest()->getParam('invoice_id')) {
+            if ($invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId)) {
+                $invoice->sendEmail();
+                $historyItem = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
+                )->getUnnotifiedForInstance(
+                    $invoice,
+                    \Magento\Sales\Model\Order\Invoice::HISTORY_ENTITY_NAME
+                );
+                if ($historyItem) {
+                    $historyItem->setIsCustomerNotified(1);
+                    $historyItem->save();
+                }
+                $this->messageManager->addSuccess(__('We sent the message.'));
+                $this->_redirect(
+                    'sales/invoice/view',
+                    array('order_id' => $invoice->getOrder()->getId(), 'invoice_id' => $invoiceId)
+                );
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..77ea54df2602f7675b971b6c34500fc97551a0df
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Grid.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+abstract class Grid extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Order grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..622da0c71df4fbaa017c6650f227de9acbf4b07d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Index.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+abstract class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Init layout, menu and breadcrumb
+     *
+     * @return $this
+     */
+    protected function _initAction()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Sales::sales_invoice'
+        )->_addBreadcrumb(
+            __('Sales'),
+            __('Sales')
+        )->_addBreadcrumb(
+            __('Invoices'),
+            __('Invoices')
+        );
+        return $this;
+    }
+
+    /**
+     * Invoices grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Invoices'));
+
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Pdfinvoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Pdfinvoices.php
new file mode 100644
index 0000000000000000000000000000000000000000..eeaee956e26e26a2c1b44226506816a337485f6c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/Pdfinvoices.php
@@ -0,0 +1,88 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+use \Magento\Framework\App\ResponseInterface;
+
+abstract class Pdfinvoices extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $invoicesIds = $this->getRequest()->getPost('invoice_ids');
+        if (!empty($invoicesIds)) {
+            $invoices = $this->_objectManager->create(
+                'Magento\Sales\Model\Resource\Order\Invoice\Collection'
+            )->addAttributeToSelect(
+                '*'
+            )->addAttributeToFilter(
+                'entity_id',
+                array('in' => $invoicesIds)
+            )->load();
+            if (!isset($pdf)) {
+                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf($invoices);
+            } else {
+                $pages = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf($invoices);
+                $pdf->pages = array_merge($pdf->pages, $pages->pages);
+            }
+            $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
+
+            return $this->_fileFactory->create(
+                'invoice' . $date . '.pdf',
+                $pdf->render(),
+                \Magento\Framework\App\Filesystem::VAR_DIR,
+                'application/pdf'
+            );
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..cae54d456a478eeb291245c332f5c6c50e81bbc0
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/PrintAction.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+use \Magento\Framework\App\ResponseInterface;
+
+abstract class PrintAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $invoiceId = $this->getRequest()->getParam('invoice_id');
+        if ($invoiceId) {
+            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
+            if ($invoice) {
+                $pdf = $this->_objectManager->create('Magento\Sales\Model\Order\Pdf\Invoice')->getPdf(array($invoice));
+                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
+                return $this->_fileFactory->create(
+                    'invoice' . $date . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            }
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..9307af6d013aac4d73f7818c35c8a8059d415401
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/AbstractInvoice/View.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice;
+
+abstract class View extends \Magento\Backend\App\Action
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Invoice information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($invoiceId = $this->getRequest()->getParam('invoice_id')) {
+            $this->_forward('view', 'order_invoice', null, array('come_from' => 'invoice'));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9d1d4aa3f89de3e0caaf645f725dd8d2813e885
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Email.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class Email extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Email
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportCsv.php
similarity index 64%
rename from app/code/Magento/Sales/Controller/Adminhtml/Invoice.php
rename to app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportCsv.php
index 4d2a3026c7732c576a18febae8713839d9185e91..5e7dbaee069857b4745b4c1b8ef0a0c0a8faee29 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Invoice.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportCsv.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,48 +22,51 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml;
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
 
-use Magento\Framework\App\ResponseInterface;
+use \Magento\Framework\App\ResponseInterface;
 
-/**
- * Adminhtml sales invoices controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Invoice extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice
+class ExportCsv extends \Magento\Backend\App\Action
 {
     /**
-     * Export invoice grid to CSV format
-     *
-     * @return ResponseInterface
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
      */
-    public function exportCsvAction()
+    protected function _isAllowed()
     {
-        $this->_view->loadLayout();
-        $fileName = 'invoices.csv';
-        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.invoice.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
     }
 
     /**
-     * Export invoice grid to Excel XML format
+     * Export invoice grid to CSV format
      *
      * @return ResponseInterface
      */
-    public function exportExcelAction()
+    public function execute()
     {
-         $this->_view->loadLayout();
-        $fileName = 'invoices.xml';
+        $this->_view->loadLayout();
+        $fileName = 'invoices.csv';
+        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
         $exportBlock = $this->_view->getLayout()->getChildBlock('sales.invoice.grid', 'grid.export');
         return $this->_fileFactory->create(
             $fileName,
-            $exportBlock->getExcelFile($fileName),
+            $exportBlock->getCsvFile(),
             \Magento\Framework\App\Filesystem::VAR_DIR
         );
     }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportExcel.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f80b7abb59ac5ea9943610930f7570a6f32a05c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/ExportExcel.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportExcel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Export invoice grid to Excel XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+         $this->_view->loadLayout();
+        $fileName = 'invoices.xml';
+        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.invoice.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ec2f7e37bd7996fd0fc757299b20f48ea070122
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Grid
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..68c490a780da688db8b71814b0d2f3086692ee99
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Index
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Pdfinvoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Pdfinvoices.php
new file mode 100644
index 0000000000000000000000000000000000000000..33ff4afafe1ef457fbb219bb141d04e2fb21139b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/Pdfinvoices.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Pdfinvoices
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..868cb5e8dbd64da2a414e1470ef7cc04b9ff1797
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/PrintAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\PrintAction
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..17c527a185cedff6a73bd009dc3774edd7c6a142
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Invoice/View.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Invoice;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order.php b/app/code/Magento/Sales/Controller/Adminhtml/Order.php
index a133311875721ced54c6189c5b79d2b0302304d1..91e1292160d4ae4b83bab4fc043186399e7c610c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order.php
@@ -116,697 +116,6 @@ class Order extends \Magento\Backend\App\Action
         return $order;
     }
 
-    /**
-     * Orders grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Orders'));
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Order grid
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * View order detail
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $this->_title->add(__('Orders'));
-
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $this->_initAction();
-            } catch (\Magento\Framework\App\Action\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('sales/order/index');
-                return;
-            } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->messageManager->addError(__('Exception occurred during order load'));
-                $this->_redirect('sales/order/index');
-                return;
-            }
-            $this->_title->add(sprintf("#%s", $order->getRealOrderId()));
-            $this->_view->renderLayout();
-        }
-    }
-
-    /**
-     * Notify user
-     *
-     * @return void
-     */
-    public function emailAction()
-    {
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $order->sendNewOrderEmail();
-                $historyItem = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
-                )->getUnnotifiedForInstance(
-                    $order,
-                    \Magento\Sales\Model\Order::HISTORY_ENTITY_NAME
-                );
-                if ($historyItem) {
-                    $historyItem->setIsCustomerNotified(1);
-                    $historyItem->save();
-                }
-                $this->messageManager->addSuccess(__('You sent the order email.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('We couldn\'t send the email order.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-        }
-        $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-    }
-
-    /**
-     * Cancel order
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $order->cancel()->save();
-                $this->messageManager->addSuccess(__('You canceled the order.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('You have not canceled the item.'));
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-        }
-    }
-
-    /**
-     * Hold order
-     *
-     * @return void
-     */
-    public function holdAction()
-    {
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $order->hold()->save();
-                $this->messageManager->addSuccess(__('You put the order on hold.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('You have not put the order on hold.'));
-            }
-            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-        }
-    }
-
-    /**
-     * Unhold order
-     *
-     * @return void
-     */
-    public function unholdAction()
-    {
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $order->unhold()->save();
-                $this->messageManager->addSuccess(__('You released the order from holding status.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('The order was not on hold.'));
-            }
-            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-        }
-    }
-
-    /**
-     * Manage payment state
-     *
-     * Either denies or approves a payment that is in "review" state
-     *
-     * @return void
-     */
-    public function reviewPaymentAction()
-    {
-        try {
-            $order = $this->_initOrder();
-            if (!$order) {
-                return;
-            }
-            $action = $this->getRequest()->getParam('action', '');
-            switch ($action) {
-                case 'accept':
-                    $order->getPayment()->accept();
-                    $message = __('The payment has been accepted.');
-                    break;
-                case 'deny':
-                    $order->getPayment()->deny();
-                    $message = __('The payment has been denied.');
-                    break;
-                case 'update':
-                    $order->getPayment()->registerPaymentReviewAction(
-                        \Magento\Sales\Model\Order\Payment::REVIEW_ACTION_UPDATE,
-                        true
-                    );
-                    $message = __('The payment update has been made.');
-                    break;
-                default:
-                    throw new \Exception(sprintf('Action "%s" is not supported.', $action));
-            }
-            $order->save();
-            $this->messageManager->addSuccess($message);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We couldn\'t update the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-    }
-
-    /**
-     * Add order comment action
-     *
-     * @return void
-     */
-    public function addCommentAction()
-    {
-        $order = $this->_initOrder();
-        if ($order) {
-            try {
-                $response = false;
-                $data = $this->getRequest()->getPost('history');
-                if (empty($data['comment']) && $data['status'] == $order->getDataByKey('status')) {
-                    throw new \Magento\Framework\Model\Exception(__('Comment text cannot be empty.'));
-                }
-
-                $notify = isset($data['is_customer_notified']) ? $data['is_customer_notified'] : false;
-                $visible = isset($data['is_visible_on_front']) ? $data['is_visible_on_front'] : false;
-
-                $history = $order->addStatusHistoryComment($data['comment'], $data['status']);
-                $history->setIsVisibleOnFront($visible);
-                $history->setIsCustomerNotified($notify);
-                $history->save();
-
-                $comment = trim(strip_tags($data['comment']));
-
-                $order->save();
-                $order->sendOrderUpdateEmail($notify, $comment);
-
-                $this->_view->loadLayout('empty');
-                $this->_view->renderLayout();
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $response = array('error' => true, 'message' => $e->getMessage());
-            } catch (\Exception $e) {
-                $response = array('error' => true, 'message' => __('We cannot add order history.'));
-            }
-            if (is_array($response)) {
-                $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
-                $this->getResponse()->representJson($response);
-            }
-        }
-    }
-
-    /**
-     * Generate invoices grid for ajax request
-     *
-     * @return void
-     */
-    public function invoicesAction()
-    {
-        $this->_initOrder();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Generate shipments grid for ajax request
-     *
-     * @return void
-     */
-    public function shipmentsAction()
-    {
-        $this->_initOrder();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Generate credit memos grid for ajax request
-     *
-     * @return void
-     */
-    public function creditmemosAction()
-    {
-        $this->_initOrder();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Generate order history for ajax request
-     *
-     * @return void
-     */
-    public function commentsHistoryAction()
-    {
-        $this->_initOrder();
-
-        $html = $this->_view->getLayout()->createBlock(
-            'Magento\Sales\Block\Adminhtml\Order\View\Tab\History'
-        )->toHtml();
-
-        $this->_translateInline->processResponseBody($html);
-
-        $this->getResponse()->setBody($html);
-    }
-
-    /**
-     * Cancel selected orders
-     *
-     * @return void
-     */
-    public function massCancelAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids', array());
-        $countCancelOrder = 0;
-        $countNonCancelOrder = 0;
-        foreach ($orderIds as $orderId) {
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-            if ($order->canCancel()) {
-                $order->cancel()->save();
-                $countCancelOrder++;
-            } else {
-                $countNonCancelOrder++;
-            }
-        }
-        if ($countNonCancelOrder) {
-            if ($countCancelOrder) {
-                $this->messageManager->addError(__('%1 order(s) cannot be canceled.', $countNonCancelOrder));
-            } else {
-                $this->messageManager->addError(__('You cannot cancel the order(s).'));
-            }
-        }
-        if ($countCancelOrder) {
-            $this->messageManager->addSuccess(__('We canceled %1 order(s).', $countCancelOrder));
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Hold selected orders
-     *
-     * @return void
-     */
-    public function massHoldAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids', array());
-        $countHoldOrder = 0;
-
-        foreach ($orderIds as $orderId) {
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-            if ($order->canHold()) {
-                $order->hold()->save();
-                $countHoldOrder++;
-            }
-        }
-
-        $countNonHoldOrder = count($orderIds) - $countHoldOrder;
-
-        if ($countNonHoldOrder) {
-            if ($countHoldOrder) {
-                $this->messageManager->addError(__('%1 order(s) were not put on hold.', $countNonHoldOrder));
-            } else {
-                $this->messageManager->addError(__('No order(s) were put on hold.'));
-            }
-        }
-        if ($countHoldOrder) {
-            $this->messageManager->addSuccess(__('You have put %1 order(s) on hold.', $countHoldOrder));
-        }
-
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Unhold selected orders
-     *
-     * @return void
-     */
-    public function massUnholdAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids', array());
-        $countUnHoldOrder = 0;
-        $countNonUnHoldOrder = 0;
-
-        foreach ($orderIds as $orderId) {
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-            if ($order->canUnhold()) {
-                $order->unhold()->save();
-                $countUnHoldOrder++;
-            } else {
-                $countNonUnHoldOrder++;
-            }
-        }
-        if ($countNonUnHoldOrder) {
-            if ($countUnHoldOrder) {
-                $this->messageManager->addError(
-                    __('%1 order(s) were not released from on hold status.', $countNonUnHoldOrder)
-                );
-            } else {
-                $this->messageManager->addError(__('No order(s) were released from on hold status.'));
-            }
-        }
-        if ($countUnHoldOrder) {
-            $this->messageManager->addSuccess(
-                __('%1 order(s) have been released from on hold status.', $countUnHoldOrder)
-            );
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Change status for selected orders
-     *
-     * @return void
-     */
-    public function massStatusAction()
-    {
-    }
-
-    /**
-     * Print documents for selected orders
-     *
-     * @return void
-     */
-    public function massPrintAction()
-    {
-    }
-
-    /**
-     * Print invoices for selected orders
-     *
-     * @return ResponseInterface|void
-     */
-    public function pdfinvoicesAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids');
-        $flag = false;
-        if (!empty($orderIds)) {
-            foreach ($orderIds as $orderId) {
-                $invoices = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Invoice\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($invoices->getSize() > 0) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Invoice'
-                        )->getPdf(
-                            $invoices
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Invoice'
-                        )->getPdf(
-                            $invoices
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-            }
-            if ($flag) {
-                return $this->_fileFactory->create(
-                    'invoice' . $this->_objectManager->get(
-                        'Magento\Framework\Stdlib\DateTime\DateTime'
-                    )->date(
-                        'Y-m-d_H-i-s'
-                    ) . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            } else {
-                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
-                $this->_redirect('sales/*/');
-            }
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Print shipments for selected orders
-     *
-     * @return ResponseInterface|void
-     */
-    public function pdfshipmentsAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids');
-        $flag = false;
-        if (!empty($orderIds)) {
-            foreach ($orderIds as $orderId) {
-                $shipments = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Shipment\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($shipments->getSize()) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Shipment'
-                        )->getPdf(
-                            $shipments
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Shipment'
-                        )->getPdf(
-                            $shipments
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-            }
-            if ($flag) {
-                return $this->_fileFactory->create(
-                    'packingslip' . $this->_objectManager->get(
-                        'Magento\Framework\Stdlib\DateTime\DateTime'
-                    )->date(
-                        'Y-m-d_H-i-s'
-                    ) . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            } else {
-                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
-                $this->_redirect('sales/*/');
-            }
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Print credit memos for selected orders
-     *
-     * @return ResponseInterface|void
-     */
-    public function pdfcreditmemosAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids');
-        $flag = false;
-        if (!empty($orderIds)) {
-            foreach ($orderIds as $orderId) {
-                $creditmemos = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($creditmemos->getSize()) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
-                        )->getPdf(
-                            $creditmemos
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
-                        )->getPdf(
-                            $creditmemos
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-            }
-            if ($flag) {
-                return $this->_fileFactory->create(
-                    'creditmemo' . $this->_objectManager->get(
-                        'Magento\Framework\Stdlib\DateTime\DateTime'
-                    )->date(
-                        'Y-m-d_H-i-s'
-                    ) . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            } else {
-                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
-                $this->_redirect('sales/*/');
-            }
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Print all documents for selected orders
-     *
-     * @return ResponseInterface|void
-     */
-    public function pdfdocsAction()
-    {
-        $orderIds = $this->getRequest()->getPost('order_ids');
-        $flag = false;
-        if (!empty($orderIds)) {
-            foreach ($orderIds as $orderId) {
-                $invoices = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Invoice\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($invoices->getSize()) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Invoice'
-                        )->getPdf(
-                            $invoices
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Invoice'
-                        )->getPdf(
-                            $invoices
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-
-                $shipments = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Shipment\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($shipments->getSize()) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Shipment'
-                        )->getPdf(
-                            $shipments
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Shipment'
-                        )->getPdf(
-                            $shipments
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-
-                $creditmemos = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
-                )->setOrderFilter(
-                    $orderId
-                )->load();
-                if ($creditmemos->getSize()) {
-                    $flag = true;
-                    if (!isset($pdf)) {
-                        $pdf = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
-                        )->getPdf(
-                            $creditmemos
-                        );
-                    } else {
-                        $pages = $this->_objectManager->create(
-                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
-                        )->getPdf(
-                            $creditmemos
-                        );
-                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
-                    }
-                }
-            }
-            if ($flag) {
-                return $this->_fileFactory->create(
-                    'docs' . $this->_objectManager->get(
-                        'Magento\Framework\Stdlib\DateTime\DateTime'
-                    )->date(
-                        'Y-m-d_H-i-s'
-                    ) . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            } else {
-                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
-                $this->_redirect('sales/*/');
-            }
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Attempt to void the order payment
-     *
-     * @return void
-     */
-    public function voidPaymentAction()
-    {
-        if (!($order = $this->_initOrder())) {
-            return;
-        }
-        try {
-            $order->getPayment()->void(new \Magento\Framework\Object()); // workaround for backwards compatibility
-            $order->save();
-            $this->messageManager->addSuccess(__('The payment has been voided.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We couldn\'t void the payment.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('sales/*/view', array('order_id' => $order->getId()));
-    }
-
     /**
      * Acl check for admin
      *
@@ -850,100 +159,4 @@ class Order extends \Magento\Backend\App\Action
         }
         return $this->_authorization->isAllowed($aclResource);
     }
-
-    /**
-     * Export order grid to CSV format
-     *
-     * @return ResponseInterface|void
-     */
-    public function exportCsvAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'orders.csv';
-        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.order.grid', 'grid.export');
-        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export order grid to Excel XML format
-     *
-     * @return ResponseInterface|void
-     */
-    public function exportExcelAction()
-    {
-        $this->_view->loadLayout();
-        $fileName = 'orders.xml';
-        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
-        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.order.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $exportBlock->getExcelFile($fileName),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
-    }
-
-    /**
-     * Order transactions grid ajax action
-     *
-     * @return void
-     */
-    public function transactionsAction()
-    {
-        $this->_initOrder();
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Edit order address form
-     *
-     * @return void
-     */
-    public function addressAction()
-    {
-        $addressId = $this->getRequest()->getParam('address_id');
-        $address = $this->_objectManager->create('Magento\Sales\Model\Order\Address')->load($addressId);
-        if ($address->getId()) {
-            $this->_coreRegistry->register('order_address', $address);
-            $this->_view->loadLayout();
-            // Do not display VAT validation button on edit order address form
-            $addressFormContainer = $this->_view->getLayout()->getBlock('sales_order_address.form.container');
-            if ($addressFormContainer) {
-                $addressFormContainer->getChildBlock('form')->setDisplayVatValidationButton(false);
-            }
-
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('sales/*/');
-        }
-    }
-
-    /**
-     * Save order address
-     *
-     * @return void
-     */
-    public function addressSaveAction()
-    {
-        $addressId = $this->getRequest()->getParam('address_id');
-        $address = $this->_objectManager->create('Magento\Sales\Model\Order\Address')->load($addressId);
-        $data = $this->getRequest()->getPost();
-        if ($data && $address->getId()) {
-            $address->addData($data);
-            try {
-                $address->save();
-                $this->messageManager->addSuccess(__('You updated the order address.'));
-                $this->_redirect('sales/*/view', array('order_id' => $address->getParentId()));
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong updating the order address.'));
-            }
-            $this->_redirect('sales/*/address', array('address_id' => $address->getId()));
-        } else {
-            $this->_redirect('sales/*/');
-        }
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php
new file mode 100644
index 0000000000000000000000000000000000000000..161e89acf41a6a06ad110f0a099754792fdd283a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddComment.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class AddComment extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Add order comment action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $response = false;
+                $data = $this->getRequest()->getPost('history');
+                if (empty($data['comment']) && $data['status'] == $order->getDataByKey('status')) {
+                    throw new \Magento\Framework\Model\Exception(__('Comment text cannot be empty.'));
+                }
+
+                $notify = isset($data['is_customer_notified']) ? $data['is_customer_notified'] : false;
+                $visible = isset($data['is_visible_on_front']) ? $data['is_visible_on_front'] : false;
+
+                $history = $order->addStatusHistoryComment($data['comment'], $data['status']);
+                $history->setIsVisibleOnFront($visible);
+                $history->setIsCustomerNotified($notify);
+                $history->save();
+
+                $comment = trim(strip_tags($data['comment']));
+
+                $order->save();
+                $order->sendOrderUpdateEmail($notify, $comment);
+
+                $this->_view->loadLayout('empty');
+                $this->_view->renderLayout();
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $response = array('error' => true, 'message' => $e->getMessage());
+            } catch (\Exception $e) {
+                $response = array('error' => true, 'message' => __('We cannot add order history.'));
+            }
+            if (is_array($response)) {
+                $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+                $this->getResponse()->representJson($response);
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Address.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Address.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc80e04408ce75cd555d8352cca16bd57b71b7d7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Address.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Address extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Edit order address form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $addressId = $this->getRequest()->getParam('address_id');
+        $address = $this->_objectManager->create('Magento\Sales\Model\Order\Address')->load($addressId);
+        if ($address->getId()) {
+            $this->_coreRegistry->register('order_address', $address);
+            $this->_view->loadLayout();
+            // Do not display VAT validation button on edit order address form
+            $addressFormContainer = $this->_view->getLayout()->getBlock('sales_order_address.form.container');
+            if ($addressFormContainer) {
+                $addressFormContainer->getChildBlock('form')->setDisplayVatValidationButton(false);
+            }
+
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('sales/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad9fce67ebde820d9a963cb7f68ea7455589788f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/AddressSave.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class AddressSave extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Save order address
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $addressId = $this->getRequest()->getParam('address_id');
+        $address = $this->_objectManager->create('Magento\Sales\Model\Order\Address')->load($addressId);
+        $data = $this->getRequest()->getPost();
+        if ($data && $address->getId()) {
+            $address->addData($data);
+            try {
+                $address->save();
+                $this->messageManager->addSuccess(__('You updated the order address.'));
+                $this->_redirect('sales/*/view', array('order_id' => $address->getParentId()));
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong updating the order address.'));
+            }
+            $this->_redirect('sales/*/address', array('address_id' => $address->getId()));
+        } else {
+            $this->_redirect('sales/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc714987297e3d002e5024a53cc6f01d9a8daced
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Cancel.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Cancel order
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $order->cancel()->save();
+                $this->messageManager->addSuccess(__('You canceled the order.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('You have not canceled the item.'));
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php
new file mode 100644
index 0000000000000000000000000000000000000000..9337ce466056663eece1280c699c59099baf574b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CommentsHistory.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class CommentsHistory extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Generate order history for ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initOrder();
+
+        $html = $this->_view->getLayout()->createBlock(
+            'Magento\Sales\Block\Adminhtml\Order\View\Tab\History'
+        )->toHtml();
+
+        $this->_translateInline->processResponseBody($html);
+
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
index 677963819af66679fc8cc64033f8e50e7d323753..cf4a3bafa9f755b20986cf0efa5bf388c458f69a 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create.php
@@ -190,7 +190,6 @@ class Create extends \Magento\Backend\App\Action
             $this->_getOrderCreateModel()->collectShippingRates();
         }
 
-
         /**
          * Apply mass changes from sidebar
          */
@@ -327,46 +326,6 @@ class Create extends \Magento\Backend\App\Action
         return $items;
     }
 
-    /**
-     * Index page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Orders'));
-        $this->_title->add(__('New Order'));
-        $this->_initSession();
-        $this->_view->loadLayout();
-
-        $this->_setActiveMenu('Magento_Sales::sales_order');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function reorderAction()
-    {
-        $this->_getSession()->clearStorage();
-        $orderId = $this->getRequest()->getParam('order_id');
-        $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-        if (!$this->_objectManager->get('Magento\Sales\Helper\Reorder')->canReorder($order)) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        if ($order->getId()) {
-            $order->setReordered(true);
-            $this->_getSession()->setUseOldShippingMethod(true);
-            $this->_getOrderCreateModel()->initFromOrder($order);
-
-            $this->_redirect('sales/*');
-        } else {
-            $this->_redirect('sales/order/');
-        }
-    }
-
     /**
      * @return $this
      */
@@ -377,175 +336,6 @@ class Create extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Loading page block
-     *
-     * @return void
-     */
-    public function loadBlockAction()
-    {
-        $request = $this->getRequest();
-        try {
-            $this->_initSession()->_processData();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->_reloadQuote();
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_reloadQuote();
-            $this->messageManager->addException($e, $e->getMessage());
-        }
-
-
-        $asJson = $request->getParam('json');
-        $block = $request->getParam('block');
-
-        $update = $this->_view->getLayout()->getUpdate();
-        if ($asJson) {
-            $update->addHandle('sales_order_create_load_block_json');
-        } else {
-            $update->addHandle('sales_order_create_load_block_plain');
-        }
-
-        if ($block) {
-            $blocks = explode(',', $block);
-            if ($asJson && !in_array('message', $blocks)) {
-                $blocks[] = 'message';
-            }
-
-            foreach ($blocks as $block) {
-                $update->addHandle('sales_order_create_load_block_' . $block);
-            }
-        }
-        $this->_view->loadLayoutUpdates();
-        $this->_view->generateLayoutXml();
-        $this->_view->generateLayoutBlocks();
-        $result = $this->_view->getLayout()->renderElement('content');
-        if ($request->getParam('as_js_varname')) {
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setUpdateResult($result);
-            $this->_redirect('sales/*/showUpdateResult');
-        } else {
-            $this->getResponse()->setBody($result);
-        }
-    }
-
-    /**
-     * Adds configured product to quote
-     *
-     * @return void
-     */
-    public function addConfiguredAction()
-    {
-        $errorMessage = null;
-        try {
-            $this->_initSession()->_processData();
-        } catch (\Exception $e) {
-            $this->_reloadQuote();
-            $errorMessage = $e->getMessage();
-        }
-
-        // Form result for client javascript
-        $updateResult = new \Magento\Framework\Object();
-        if ($errorMessage) {
-            $updateResult->setError(true);
-            $updateResult->setMessage($errorMessage);
-        } else {
-            $updateResult->setOk(true);
-        }
-
-        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
-        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
-        $this->_redirect('catalog/product/showUpdateResult');
-    }
-
-    /**
-     * Start order create action
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        $this->_getSession()->clearStorage();
-        $this->_redirect('sales/*', array('customer_id' => $this->getRequest()->getParam('customer_id')));
-    }
-
-    /**
-     * Cancel order create
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        if ($orderId = $this->_getSession()->getReordered()) {
-            $this->_getSession()->clearStorage();
-            $this->_redirect('sales/order/view', array('order_id' => $orderId));
-        } else {
-            $this->_getSession()->clearStorage();
-            $this->_redirect('sales/*');
-        }
-    }
-
-    /**
-     * Saving quote and create order
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        try {
-            // check if the creation of a new customer is allowed
-            if (!$this->_authorization->isAllowed('Magento_Customer::manage')
-                && !$this->_getSession()->getCustomerId()
-                && !$this->_getSession()->getQuote()->getCustomerIsGuest()
-            ) {
-                $this->_forward('denied');
-                return;
-            }
-            $this->_processActionData('save');
-            $paymentData = $this->getRequest()->getPost('payment');
-            if ($paymentData) {
-                $paymentData['checks'] = array(
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_INTERNAL,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
-                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
-                );
-                $this->_getOrderCreateModel()->setPaymentData($paymentData);
-                $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($paymentData);
-            }
-
-            $order = $this->_getOrderCreateModel()->setIsValidate(
-                true
-            )->importPostData(
-                $this->getRequest()->getPost('order')
-            )->createOrder();
-
-            $this->_getSession()->clearStorage();
-            $this->messageManager->addSuccess(__('You created the order.'));
-            if ($this->_authorization->isAllowed('Magento_Sales::actions_view')) {
-                $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
-            } else {
-                $this->_redirect('sales/order/index');
-            }
-        } catch (\Magento\Payment\Model\Info\Exception $e) {
-            $this->_getOrderCreateModel()->saveQuote();
-            $message = $e->getMessage();
-            if (!empty($message)) {
-                $this->messageManager->addError($message);
-            }
-            $this->_redirect('sales/*/');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $message = $e->getMessage();
-            if (!empty($message)) {
-                $this->messageManager->addError($message);
-            }
-            $this->_redirect('sales/*/');
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Order saving error: %1', $e->getMessage()));
-            $this->_redirect('sales/*/');
-        }
-    }
-
     /**
      * Acl check for admin
      *
@@ -584,105 +374,4 @@ class Create extends \Magento\Backend\App\Action
         }
         return $aclResource;
     }
-
-    /**
-     * Ajax handler to response configuration fieldset of composite product in order
-     *
-     * @return void
-     */
-    public function configureProductToAddAction()
-    {
-        // Prepare data
-        $productId = (int)$this->getRequest()->getParam('id');
-
-        $configureResult = new \Magento\Framework\Object();
-        $configureResult->setOk(true);
-        $configureResult->setProductId($productId);
-        $sessionQuote = $this->_objectManager->get('Magento\Backend\Model\Session\Quote');
-        $configureResult->setCurrentStoreId($sessionQuote->getStore()->getId());
-        $configureResult->setCurrentCustomerId($sessionQuote->getCustomerId());
-
-        // Render page
-        $this->_objectManager->get(
-            'Magento\Catalog\Helper\Product\Composite'
-        )->renderConfigureResult(
-            $configureResult
-        );
-    }
-
-    /**
-     * Ajax handler to response configuration fieldset of composite product in quote items
-     *
-     * @return void
-     */
-    public function configureQuoteItemsAction()
-    {
-        // Prepare data
-        $configureResult = new \Magento\Framework\Object();
-        try {
-            $quoteItemId = (int)$this->getRequest()->getParam('id');
-            if (!$quoteItemId) {
-                throw new \Magento\Framework\Model\Exception(__('Quote item id is not received.'));
-            }
-
-            $quoteItem = $this->_objectManager->create('Magento\Sales\Model\Quote\Item')->load($quoteItemId);
-            if (!$quoteItem->getId()) {
-                throw new \Magento\Framework\Model\Exception(__('Quote item is not loaded.'));
-            }
-
-            $configureResult->setOk(true);
-            $optionCollection = $this->_objectManager->create(
-                'Magento\Sales\Model\Quote\Item\Option'
-            )->getCollection()->addItemFilter(
-                array($quoteItemId)
-            );
-            $quoteItem->setOptions($optionCollection->getOptionsByItem($quoteItem));
-
-            $configureResult->setBuyRequest($quoteItem->getBuyRequest());
-            $configureResult->setCurrentStoreId($quoteItem->getStoreId());
-            $configureResult->setProductId($quoteItem->getProductId());
-            $sessionQuote = $this->_objectManager->get('Magento\Backend\Model\Session\Quote');
-            $configureResult->setCurrentCustomerId($sessionQuote->getCustomerId());
-        } catch (\Exception $e) {
-            $configureResult->setError(true);
-            $configureResult->setMessage($e->getMessage());
-        }
-
-        // Render page
-        $this->_objectManager->get(
-            'Magento\Catalog\Helper\Product\Composite'
-        )->renderConfigureResult(
-            $configureResult
-        );
-    }
-
-    /**
-     * Show item update result from loadBlockAction
-     * to prevent popup alert with resend data question
-     *
-     * @return void|false
-     */
-    public function showUpdateResultAction()
-    {
-        $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-        if ($session->hasUpdateResult() && is_scalar($session->getUpdateResult())) {
-            $this->getResponse()->setBody($session->getUpdateResult());
-            $session->unsUpdateResult();
-        } else {
-            $session->unsUpdateResult();
-            return false;
-        }
-    }
-
-    /**
-     * Process data and display index page
-     *
-     * @return void
-     */
-    public function processDataAction()
-    {
-        $this->_initSession();
-        $this->_processData();
-        $this->_forward('index');
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/AddConfigured.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/AddConfigured.php
new file mode 100644
index 0000000000000000000000000000000000000000..43412ca010afd82fe92f3cd593b19a4e243de7e0
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/AddConfigured.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class AddConfigured extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Adds configured product to quote
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $errorMessage = null;
+        try {
+            $this->_initSession()->_processData();
+        } catch (\Exception $e) {
+            $this->_reloadQuote();
+            $errorMessage = $e->getMessage();
+        }
+
+        // Form result for client javascript
+        $updateResult = new \Magento\Framework\Object();
+        if ($errorMessage) {
+            $updateResult->setError(true);
+            $updateResult->setMessage($errorMessage);
+        } else {
+            $updateResult->setOk(true);
+        }
+
+        $updateResult->setJsVarName($this->getRequest()->getParam('as_js_varname'));
+        $this->_objectManager->get('Magento\Backend\Model\Session')->setCompositeProductResult($updateResult);
+        $this->_redirect('catalog/product/showUpdateResult');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..dc0b27028d0060dec8bd305f0d90050125495184
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Cancel.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Cancel order create
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($orderId = $this->_getSession()->getReordered()) {
+            $this->_getSession()->clearStorage();
+            $this->_redirect('sales/order/view', array('order_id' => $orderId));
+        } else {
+            $this->_getSession()->clearStorage();
+            $this->_redirect('sales/*');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureProductToAdd.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureProductToAdd.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec142c3860e6507bc0b5149dc6ddc95d6496d544
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureProductToAdd.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class ConfigureProductToAdd extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Ajax handler to response configuration fieldset of composite product in order
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // Prepare data
+        $productId = (int)$this->getRequest()->getParam('id');
+
+        $configureResult = new \Magento\Framework\Object();
+        $configureResult->setOk(true);
+        $configureResult->setProductId($productId);
+        $sessionQuote = $this->_objectManager->get('Magento\Backend\Model\Session\Quote');
+        $configureResult->setCurrentStoreId($sessionQuote->getStore()->getId());
+        $configureResult->setCurrentCustomerId($sessionQuote->getCustomerId());
+
+        // Render page
+        $this->_objectManager->get(
+            'Magento\Catalog\Helper\Product\Composite'
+        )->renderConfigureResult(
+            $configureResult
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureQuoteItems.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureQuoteItems.php
new file mode 100644
index 0000000000000000000000000000000000000000..71789d7729076ef471cc107d43b0a1153e5127ad
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ConfigureQuoteItems.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class ConfigureQuoteItems extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Ajax handler to response configuration fieldset of composite product in quote items
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // Prepare data
+        $configureResult = new \Magento\Framework\Object();
+        try {
+            $quoteItemId = (int)$this->getRequest()->getParam('id');
+            if (!$quoteItemId) {
+                throw new \Magento\Framework\Model\Exception(__('Quote item id is not received.'));
+            }
+
+            $quoteItem = $this->_objectManager->create('Magento\Sales\Model\Quote\Item')->load($quoteItemId);
+            if (!$quoteItem->getId()) {
+                throw new \Magento\Framework\Model\Exception(__('Quote item is not loaded.'));
+            }
+
+            $configureResult->setOk(true);
+            $optionCollection = $this->_objectManager->create(
+                'Magento\Sales\Model\Quote\Item\Option'
+            )->getCollection()->addItemFilter(
+                array($quoteItemId)
+            );
+            $quoteItem->setOptions($optionCollection->getOptionsByItem($quoteItem));
+
+            $configureResult->setBuyRequest($quoteItem->getBuyRequest());
+            $configureResult->setCurrentStoreId($quoteItem->getStoreId());
+            $configureResult->setProductId($quoteItem->getProductId());
+            $sessionQuote = $this->_objectManager->get('Magento\Backend\Model\Session\Quote');
+            $configureResult->setCurrentCustomerId($sessionQuote->getCustomerId());
+        } catch (\Exception $e) {
+            $configureResult->setError(true);
+            $configureResult->setMessage($e->getMessage());
+        }
+
+        // Render page
+        $this->_objectManager->get(
+            'Magento\Catalog\Helper\Product\Composite'
+        )->renderConfigureResult(
+            $configureResult
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..1661c6bd603eb6bf9a006b3f6f69337710bfe88b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Index.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Index page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Orders'));
+        $this->_title->add(__('New Order'));
+        $this->_initSession();
+        $this->_view->loadLayout();
+
+        $this->_setActiveMenu('Magento_Sales::sales_order');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..e249c4424061d09296cb40db0e6c40f4ab531ebc
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/LoadBlock.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class LoadBlock extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Loading page block
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+        try {
+            $this->_initSession()->_processData();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->_reloadQuote();
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_reloadQuote();
+            $this->messageManager->addException($e, $e->getMessage());
+        }
+
+
+        $asJson = $request->getParam('json');
+        $block = $request->getParam('block');
+
+        $update = $this->_view->getLayout()->getUpdate();
+        if ($asJson) {
+            $update->addHandle('sales_order_create_load_block_json');
+        } else {
+            $update->addHandle('sales_order_create_load_block_plain');
+        }
+
+        if ($block) {
+            $blocks = explode(',', $block);
+            if ($asJson && !in_array('message', $blocks)) {
+                $blocks[] = 'message';
+            }
+
+            foreach ($blocks as $block) {
+                $update->addHandle('sales_order_create_load_block_' . $block);
+            }
+        }
+        $this->_view->loadLayoutUpdates();
+        $this->_view->generateLayoutXml();
+        $this->_view->generateLayoutBlocks();
+        $result = $this->_view->getLayout()->renderElement('content');
+        if ($request->getParam('as_js_varname')) {
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setUpdateResult($result);
+            $this->_redirect('sales/*/showUpdateResult');
+        } else {
+            $this->getResponse()->setBody($result);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ProcessData.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ProcessData.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c1939e91e908b93d83071acdd36724008ce5f30
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ProcessData.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class ProcessData extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Process data and display index page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initSession();
+        $this->_processData();
+        $this->_forward('index');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Reorder.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..fce06e9924da71963a265ed96462c935adf4aed8
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Reorder.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class Reorder extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getSession()->clearStorage();
+        $orderId = $this->getRequest()->getParam('order_id');
+        $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+        if (!$this->_objectManager->get('Magento\Sales\Helper\Reorder')->canReorder($order)) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        if ($order->getId()) {
+            $order->setReordered(true);
+            $this->_getSession()->setUseOldShippingMethod(true);
+            $this->_getOrderCreateModel()->initFromOrder($order);
+
+            $this->_redirect('sales/*');
+        } else {
+            $this->_redirect('sales/order/');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..84f43672af8f7e7918b0bd75dfa4315db9215c7e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Save.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Saving quote and create order
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            // check if the creation of a new customer is allowed
+            if (!$this->_authorization->isAllowed('Magento_Customer::manage')
+                && !$this->_getSession()->getCustomerId()
+                && !$this->_getSession()->getQuote()->getCustomerIsGuest()
+            ) {
+                $this->_forward('denied');
+                return;
+            }
+            $this->_processActionData('save');
+            $paymentData = $this->getRequest()->getPost('payment');
+            if ($paymentData) {
+                $paymentData['checks'] = array(
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_INTERNAL,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_COUNTRY,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_USE_FOR_CURRENCY,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ORDER_TOTAL_MIN_MAX,
+                    \Magento\Payment\Model\Method\AbstractMethod::CHECK_ZERO_TOTAL
+                );
+                $this->_getOrderCreateModel()->setPaymentData($paymentData);
+                $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($paymentData);
+            }
+
+            $order = $this->_getOrderCreateModel()->setIsValidate(
+                true
+            )->importPostData(
+                $this->getRequest()->getPost('order')
+            )->createOrder();
+
+            $this->_getSession()->clearStorage();
+            $this->messageManager->addSuccess(__('You created the order.'));
+            if ($this->_authorization->isAllowed('Magento_Sales::actions_view')) {
+                $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+            } else {
+                $this->_redirect('sales/order/index');
+            }
+        } catch (\Magento\Payment\Model\Info\Exception $e) {
+            $this->_getOrderCreateModel()->saveQuote();
+            $message = $e->getMessage();
+            if (!empty($message)) {
+                $this->messageManager->addError($message);
+            }
+            $this->_redirect('sales/*/');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $message = $e->getMessage();
+            if (!empty($message)) {
+                $this->messageManager->addError($message);
+            }
+            $this->_redirect('sales/*/');
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Order saving error: %1', $e->getMessage()));
+            $this->_redirect('sales/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f7969918d0a3cf8c008fb9cdc596e30b8b9ae85
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/ShowUpdateResult.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Show item update result from loadBlockAction
+     * to prevent popup alert with resend data question
+     *
+     * @return void|false
+     */
+    public function execute()
+    {
+        $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+        if ($session->hasUpdateResult() && is_scalar($session->getUpdateResult())) {
+            $this->getResponse()->setBody($session->getUpdateResult());
+            $session->unsUpdateResult();
+        } else {
+            $session->unsUpdateResult();
+            return false;
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..88289179b4337348a6eb347b43c93e35b8621d7c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Create/Start.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Create;
+
+use \Magento\Backend\App\Action;
+
+class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Start order create action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_getSession()->clearStorage();
+        $this->_redirect('sales/*', array('customer_id' => $this->getRequest()->getParam('customer_id')));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php
deleted file mode 100644
index 407c9c46c298951d1d877ac3d32c8032ca230c99..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo.php
+++ /dev/null
@@ -1,460 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller\Adminhtml\Order;
-
-use Magento\Sales\Model\Order;
-use Magento\Framework\App\ResponseInterface;
-
-/**
- * Adminhtml sales order creditmemo controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Creditmemo extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo
-{
-    /**
-     * Get requested items qtys and return to stock flags
-     *
-     * @return array
-     */
-    protected function _getItemData()
-    {
-        $data = $this->getRequest()->getParam('creditmemo');
-        if (!$data) {
-            $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
-        }
-
-        if (isset($data['items'])) {
-            $qtys = $data['items'];
-        } else {
-            $qtys = array();
-        }
-        return $qtys;
-    }
-
-    /**
-     * Check if creditmeno can be created for order
-     * @param Order $order
-     * @return bool
-     */
-    protected function _canCreditmemo($order)
-    {
-        /**
-         * Check order existing
-         */
-        if (!$order->getId()) {
-            $this->messageManager->addError(__('The order no longer exists.'));
-            return false;
-        }
-
-        /**
-         * Check creditmemo create availability
-         */
-        if (!$order->canCreditmemo()) {
-            $this->messageManager->addError(__('Cannot create credit memo for the order.'));
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Initialize requested invoice instance
-     *
-     * @param Order $order
-     * @return bool
-     */
-    protected function _initInvoice($order)
-    {
-        $invoiceId = $this->getRequest()->getParam('invoice_id');
-        if ($invoiceId) {
-            $invoice = $this->_objectManager->create(
-                'Magento\Sales\Model\Order\Invoice'
-            )->load(
-                $invoiceId
-            )->setOrder(
-                $order
-            );
-            if ($invoice->getId()) {
-                return $invoice;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Initialize creditmemo model instance
-     *
-     * @param bool $update
-     * @return \Magento\Sales\Model\Order\Creditmemo|false
-     */
-    protected function _initCreditmemo($update = false)
-    {
-        $this->_title->add(__('Credit Memos'));
-
-        $creditmemo = false;
-        $creditmemoId = $this->getRequest()->getParam('creditmemo_id');
-        $orderId = $this->getRequest()->getParam('order_id');
-        if ($creditmemoId) {
-            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
-        } elseif ($orderId) {
-            $data = $this->getRequest()->getParam('creditmemo');
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-            $invoice = $this->_initInvoice($order);
-
-            if (!$this->_canCreditmemo($order)) {
-                return false;
-            }
-
-            $savedData = $this->_getItemData();
-
-            $qtys = array();
-            $backToStock = array();
-            foreach ($savedData as $orderItemId => $itemData) {
-                if (isset($itemData['qty'])) {
-                    $qtys[$orderItemId] = $itemData['qty'];
-                }
-                if (isset($itemData['back_to_stock'])) {
-                    $backToStock[$orderItemId] = true;
-                }
-            }
-            $data['qtys'] = $qtys;
-
-            $service = $this->_objectManager->create('Magento\Sales\Model\Service\Order', array('order' => $order));
-            if ($invoice) {
-                $creditmemo = $service->prepareInvoiceCreditmemo($invoice, $data);
-            } else {
-                $creditmemo = $service->prepareCreditmemo($data);
-            }
-
-            /**
-             * Process back to stock flags
-             */
-            foreach ($creditmemo->getAllItems() as $creditmemoItem) {
-                $orderItem = $creditmemoItem->getOrderItem();
-                $parentId = $orderItem->getParentItemId();
-                if (isset($backToStock[$orderItem->getId()])) {
-                    $creditmemoItem->setBackToStock(true);
-                } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
-                    $creditmemoItem->setBackToStock(true);
-                } elseif (empty($savedData)) {
-                    $creditmemoItem->setBackToStock(
-                        $this->_objectManager->get('Magento\CatalogInventory\Helper\Data')->isAutoReturnEnabled()
-                    );
-                } else {
-                    $creditmemoItem->setBackToStock(false);
-                }
-            }
-        }
-
-        $this->_eventManager->dispatch(
-            'adminhtml_sales_order_creditmemo_register_before',
-            array('creditmemo' => $creditmemo, 'request' => $this->getRequest())
-        );
-
-        $this->_objectManager->get('Magento\Framework\Registry')->register('current_creditmemo', $creditmemo);
-        return $creditmemo;
-    }
-
-    /**
-     * Save creditmemo and related order, invoice in one transaction
-     *
-     * @param \Magento\Sales\Model\Order\Creditmemo $creditmemo
-     * @return $this
-     */
-    protected function _saveCreditmemo($creditmemo)
-    {
-        $transactionSave = $this->_objectManager->create(
-            'Magento\Framework\DB\Transaction'
-        )->addObject(
-            $creditmemo
-        )->addObject(
-            $creditmemo->getOrder()
-        );
-        if ($creditmemo->getInvoice()) {
-            $transactionSave->addObject($creditmemo->getInvoice());
-        }
-        $transactionSave->save();
-
-        return $this;
-    }
-
-    /**
-     * Creditmemo information page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $creditmemo = $this->_initCreditmemo();
-        if ($creditmemo) {
-            if ($creditmemo->getInvoice()) {
-                $this->_title->add(__("View Memo for #%1", $creditmemo->getInvoice()->getIncrementId()));
-            } else {
-                $this->_title->add(__("View Memo"));
-            }
-
-            $this->_view->loadLayout();
-            $this->_view->getLayout()->getBlock(
-                'sales_creditmemo_view'
-            )->updateBackButtonUrl(
-                $this->getRequest()->getParam('come_from')
-            );
-            $this->_setActiveMenu('Magento_Sales::sales_creditmemo');
-            $this->_view->renderLayout();
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Start create creditmemo action
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        /**
-         * Clear old values for creditmemo qty's
-         */
-        $this->_redirect('sales/*/new', array('_current' => true));
-    }
-
-    /**
-     * Creditmemo create page
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        if ($creditmemo = $this->_initCreditmemo()) {
-            if ($creditmemo->getInvoice()) {
-                $this->_title->add(__("New Memo for #%1", $creditmemo->getInvoice()->getIncrementId()));
-            } else {
-                $this->_title->add(__("New Memo"));
-            }
-
-            if ($comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true)) {
-                $creditmemo->setCommentText($comment);
-            }
-
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Sales::sales_order');
-            $this->_view->renderLayout();
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Update items qty action
-     *
-     * @return void
-     */
-    public function updateQtyAction()
-    {
-        try {
-            $this->_initCreditmemo(true);
-            $this->_view->loadLayout();
-            $response = $this->_view->getLayout()->getBlock('order_items')->toHtml();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot update the item\'s quantity.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Save creditmemo
-     * We can save only new creditmemo. Existing creditmemos are not editable
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost('creditmemo');
-        if (!empty($data['comment_text'])) {
-            $this->_getSession()->setCommentText($data['comment_text']);
-        }
-        try {
-            $creditmemo = $this->_initCreditmemo();
-            if ($creditmemo) {
-                if ($creditmemo->getGrandTotal() <= 0 && !$creditmemo->getAllowZeroGrandTotal()) {
-                    throw new \Magento\Framework\Model\Exception(__('Credit memo\'s total must be positive.'));
-                }
-
-                $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'];
-                    }
-                }
-
-                if (isset($data['do_refund'])) {
-                    $creditmemo->setRefundRequested(true);
-                }
-                if (isset($data['do_offline'])) {
-                    //do not allow online refund for Refund to Store Credit
-                    if (!$data['do_offline'] && !empty($data['refund_customerbalance_return_enable'])) {
-                        throw new \Magento\Framework\Model\Exception(
-                            __('Cannot create online refund for Refund to Store Credit.')
-                        );
-                    }
-                    $creditmemo->setOfflineRequested((bool)(int)$data['do_offline']);
-                }
-
-                $creditmemo->register();
-                if (!empty($data['send_email'])) {
-                    $creditmemo->setEmailSent(true);
-                }
-
-                $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
-                $this->_saveCreditmemo($creditmemo);
-                $creditmemo->sendEmail(!empty($data['send_email']), $comment);
-                $this->messageManager->addSuccess(__('You created the credit memo.'));
-                $this->_getSession()->getCommentText(true);
-                $this->_redirect('sales/order/view', array('order_id' => $creditmemo->getOrderId()));
-                return;
-            } else {
-                $this->_forward('noroute');
-                return;
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_getSession()->setFormData($data);
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__('Cannot save the credit memo.'));
-        }
-        $this->_redirect('sales/*/new', array('_current' => true));
-    }
-
-    /**
-     * Cancel creditmemo action
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $creditmemo = $this->_initCreditmemo();
-        if ($creditmemo) {
-            try {
-                $creditmemo->cancel();
-                $this->_saveCreditmemo($creditmemo);
-                $this->messageManager->addSuccess(__('The credit memo has been canceled.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('You canceled the credit memo.'));
-            }
-            $this->_redirect('sales/*/view', array('creditmemo_id' => $creditmemo->getId()));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Void creditmemo action
-     *
-     * @return void
-     */
-    public function voidAction()
-    {
-        $creditmemo = $this->_initCreditmemo();
-        if ($creditmemo) {
-            try {
-                $creditmemo->void();
-                $this->_saveCreditmemo($creditmemo);
-                $this->messageManager->addSuccess(__('You voided the credit memo.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('We can\'t void the credit memo.'));
-            }
-            $this->_redirect('sales/*/view', array('creditmemo_id' => $creditmemo->getId()));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Add comment to creditmemo history
-     *
-     * @return void
-     */
-    public function addCommentAction()
-    {
-        try {
-            $this->getRequest()->setParam('creditmemo_id', $this->getRequest()->getParam('id'));
-            $data = $this->getRequest()->getPost('comment');
-            if (empty($data['comment'])) {
-                throw new \Magento\Framework\Model\Exception(__('The Comment Text field cannot be empty.'));
-            }
-            $creditmemo = $this->_initCreditmemo();
-            $comment = $creditmemo->addComment(
-                $data['comment'],
-                isset($data['is_customer_notified']),
-                isset($data['is_visible_on_front'])
-            );
-            $comment->save();
-            $creditmemo->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
-
-            $this->_view->loadLayout();
-            $response = $this->_view->getLayout()->getBlock('creditmemo_comments')->toHtml();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Create pdf for current creditmemo
-     *
-     * @return ResponseInterface|void
-     */
-    public function printAction()
-    {
-        $this->_initCreditmemo();
-        parent::printAction();
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php
new file mode 100644
index 0000000000000000000000000000000000000000..eba5f4c1422cce7d018de42eae51bade211b895f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/AddComment.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use Magento\Backend\App\Action;
+
+class AddComment extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Add comment to creditmemo history
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getRequest()->setParam('creditmemo_id', $this->getRequest()->getParam('id'));
+            $data = $this->getRequest()->getPost('comment');
+            if (empty($data['comment'])) {
+                throw new \Magento\Framework\Model\Exception(__('The Comment Text field cannot be empty.'));
+            }
+            $this->_title->add(__('Credit Memos'));
+            $creditmemo = $this->creditmemoLoader->load($this->_request);
+            $comment = $creditmemo->addComment(
+                $data['comment'],
+                isset($data['is_customer_notified']),
+                isset($data['is_visible_on_front'])
+            );
+            $comment->save();
+            $creditmemo->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
+
+            $this->_view->loadLayout();
+            $response = $this->_view->getLayout()->getBlock('creditmemo_comments')->toHtml();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..e81ca9f0e18fd57dd7dc5e038d72cad505292dda
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Cancel.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use \Magento\Backend\App\Action;
+
+class Cancel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Cancel creditmemo action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $creditmemo = $this->creditmemoLoader->load($this->_request);
+        if ($creditmemo) {
+            try {
+                $creditmemo->cancel();
+                $transactionSave = $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $creditmemo
+                )->addObject(
+                    $creditmemo->getOrder()
+                );
+                if ($creditmemo->getInvoice()) {
+                    $transactionSave->addObject($creditmemo->getInvoice());
+                }
+                $transactionSave->save();
+                $this->messageManager->addSuccess(__('The credit memo has been canceled.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('You canceled the credit memo.'));
+            }
+            $this->_redirect('sales/*/view', array('creditmemo_id' => $creditmemo->getId()));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..22151f2f3a2021ee019e1551114eb0c7153f4d2e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Email.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+class Email extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Email
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..e3972f9e7f23379c2cdfb21ef44d92ccd1f42b1d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Grid
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f259bca61742644a4a651a3c8f5523f18576fb7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Index
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..4bb35add576d128d461d68735a9b58ea8a33017d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/NewAction.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use Magento\Backend\App\Action;
+
+class NewAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Creditmemo create page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Credit Memos'));
+        if ($creditmemo = $this->creditmemoLoader->load($this->_request)) {
+            if ($creditmemo->getInvoice()) {
+                $this->_title->add(__("New Memo for #%1", $creditmemo->getInvoice()->getIncrementId()));
+            } else {
+                $this->_title->add(__("New Memo"));
+            }
+
+            if ($comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true)) {
+                $creditmemo->setCommentText($comment);
+            }
+
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Sales::sales_order');
+            $this->_view->renderLayout();
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Pdfcreditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Pdfcreditmemos.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c6c07bafc2bc1328e201124ba00ee245b883364
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Pdfcreditmemos.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+class Pdfcreditmemos extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\Pdfcreditmemos
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..519ae1c3179c57432318c1b8001979589a23be4c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/PrintAction.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use \Magento\Framework\App\ResponseInterface;
+use Magento\Backend\App\Action;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Creditmemo\AbstractCreditmemo\PrintAction
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context, $fileFactory);
+    }
+
+    /**
+     * Create pdf for current creditmemo
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Credit Memos'));
+        $this->creditmemoLoader->load($this->_request);
+        parent::execute();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc9d8d695b574a226d5eb801464e816b2e1f6b05
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Save.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use \Magento\Sales\Model\Order;
+use \Magento\Backend\App\Action;
+
+class Save extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Save creditmemo
+     * We can save only new creditmemo. Existing creditmemos are not editable
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost('creditmemo');
+        if (!empty($data['comment_text'])) {
+            $this->_getSession()->setCommentText($data['comment_text']);
+        }
+        try {
+            $creditmemo = $this->creditmemoLoader->load($this->_request);
+            if ($creditmemo) {
+                if ($creditmemo->getGrandTotal() <= 0 && !$creditmemo->getAllowZeroGrandTotal()) {
+                    throw new \Magento\Framework\Model\Exception(__('Credit memo\'s total must be positive.'));
+                }
+
+                $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'];
+                    }
+                }
+
+                if (isset($data['do_refund'])) {
+                    $creditmemo->setRefundRequested(true);
+                }
+                if (isset($data['do_offline'])) {
+                    //do not allow online refund for Refund to Store Credit
+                    if (!$data['do_offline'] && !empty($data['refund_customerbalance_return_enable'])) {
+                        throw new \Magento\Framework\Model\Exception(
+                            __('Cannot create online refund for Refund to Store Credit.')
+                        );
+                    }
+                    $creditmemo->setOfflineRequested((bool)(int)$data['do_offline']);
+                }
+
+                $creditmemo->register();
+                if (!empty($data['send_email'])) {
+                    $creditmemo->setEmailSent(true);
+                }
+
+                $creditmemo->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
+                $transactionSave = $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $creditmemo
+                )->addObject(
+                    $creditmemo->getOrder()
+                );
+                if ($creditmemo->getInvoice()) {
+                    $transactionSave->addObject($creditmemo->getInvoice());
+                }
+                $transactionSave->save();
+                $creditmemo->sendEmail(!empty($data['send_email']), $comment);
+                $this->messageManager->addSuccess(__('You created the credit memo.'));
+                $this->_getSession()->getCommentText(true);
+                $this->_redirect('sales/order/view', array('order_id' => $creditmemo->getOrderId()));
+                return;
+            } else {
+                $this->_forward('noroute');
+                return;
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_getSession()->setFormData($data);
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__('Cannot save the credit memo.'));
+        }
+        $this->_redirect('sales/*/new', array('_current' => true));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..57722f35c02eb0f20883a9db9b0c53e385ac7796
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Start.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+class Start extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Start create creditmemo action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /**
+         * Clear old values for creditmemo qty's
+         */
+        $this->_redirect('sales/*/new', array('_current' => true));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php
new file mode 100644
index 0000000000000000000000000000000000000000..204301727b9fa38daec78c7e3645cb869c4e0d15
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/UpdateQty.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use \Magento\Backend\App\Action;
+
+class UpdateQty extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Update items qty action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $creditmemo = $this->creditmemoLoader->load($this->_request, true);
+            $this->_view->loadLayout();
+            $response = $this->_view->getLayout()->getBlock('order_items')->toHtml();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot update the item\'s quantity.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..5ee636fb6b3c49c75569678d2eccb1553e8d3890
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/View.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use Magento\Backend\App\Action;
+
+class View extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Creditmemo information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $creditmemo = $this->creditmemoLoader->load($this->_request);
+        if ($creditmemo) {
+            if ($creditmemo->getInvoice()) {
+                $this->_title->add(__("View Memo for #%1", $creditmemo->getInvoice()->getIncrementId()));
+            } else {
+                $this->_title->add(__("View Memo"));
+            }
+
+            $this->_view->loadLayout();
+            $this->_view->getLayout()->getBlock(
+                'sales_creditmemo_view'
+            )->updateBackButtonUrl(
+                $this->getRequest()->getParam('come_from')
+            );
+            $this->_setActiveMenu('Magento_Sales::sales_creditmemo');
+            $this->_view->renderLayout();
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Void.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Void.php
new file mode 100644
index 0000000000000000000000000000000000000000..4865b62e5060aab3c7496a1fe042a7d771dfae33
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/Void.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
+
+use Magento\Backend\App\Action;
+
+class Void extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader
+     */
+    protected $creditmemoLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader $creditmemoLoader
+    ) {
+        $this->creditmemoLoader = $creditmemoLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_creditmemo');
+    }
+
+    /**
+     * Void creditmemo action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $creditmemo = $this->creditmemoLoader->load($this->_request);
+        if ($creditmemo) {
+            try {
+                $creditmemo->void();
+                $transactionSave = $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $creditmemo
+                )->addObject(
+                    $creditmemo->getOrder()
+                );
+                if ($creditmemo->getInvoice()) {
+                    $transactionSave->addObject($creditmemo->getInvoice());
+                }
+                $transactionSave->save();
+                $this->messageManager->addSuccess(__('You voided the credit memo.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('We can\'t void the credit memo.'));
+            }
+            $this->_redirect('sales/*/view', array('creditmemo_id' => $creditmemo->getId()));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..cef61ceaedc68469303b787c0cb026d9b500581e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/CreditmemoLoader.php
@@ -0,0 +1,248 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use Magento\Framework\App\RequestInterface;
+
+class CreditmemoLoader
+{
+    /**
+     * @var \Magento\Sales\Model\Order\CreditmemoFactory
+     */
+    protected $creditmemoFactory;
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Sales\Model\Order\InvoiceFactory
+     */
+    protected $invoiceFactory;
+
+    /**
+     * @var \Magento\Sales\Model\Service\OrderFactory
+     */
+    protected $orderServiceFactory;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * @var \Magento\Backend\Model\Session
+     */
+    protected $backendSession;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @var \Magento\CatalogInventory\Helper\Data
+     */
+    protected $inventoryHelper;
+
+    /**
+     * @param \Magento\Sales\Model\Order\CreditmemoFactory $creditmemoFactory
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Sales\Model\Order\InvoiceFactory $invoiceFactory
+     * @param \Magento\Sales\Model\Service\OrderFactory $orderServiceFactory
+     * @param \Magento\Framework\Event\ManagerInterface $eventManager
+     * @param \Magento\Backend\Model\Session $backendSession
+     * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\CatalogInventory\Helper\Data $inventoryHelper
+     */
+    public function __construct(
+        \Magento\Sales\Model\Order\CreditmemoFactory $creditmemoFactory,
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Sales\Model\Order\InvoiceFactory $invoiceFactory,
+        \Magento\Sales\Model\Service\OrderFactory $orderServiceFactory,
+        \Magento\Framework\Event\ManagerInterface $eventManager,
+        \Magento\Backend\Model\Session $backendSession,
+        \Magento\Framework\Message\ManagerInterface $messageManager,
+        \Magento\Framework\Registry $registry,
+        \Magento\CatalogInventory\Helper\Data $inventoryHelper
+    ) {
+        $this->creditmemoFactory = $creditmemoFactory;
+        $this->orderFactory = $orderFactory;
+        $this->invoiceFactory = $invoiceFactory;
+        $this->orderServiceFactory = $orderServiceFactory;
+        $this->eventManager = $eventManager;
+        $this->backendSession = $backendSession;
+        $this->messageManager = $messageManager;
+        $this->registry = $registry;
+        $this->inventoryHelper = $inventoryHelper;
+    }
+
+    /**
+     * Get requested items qtys and return to stock flags
+     *
+     * @param RequestInterface $request
+     * @return array
+     */
+    protected function _getItemData(RequestInterface $request)
+    {
+        $data = $request->getParam('creditmemo');
+        if (!$data) {
+            $data = $this->backendSession->getFormData(true);
+        }
+
+        if (isset($data['items'])) {
+            $qtys = $data['items'];
+        } else {
+            $qtys = array();
+        }
+        return $qtys;
+    }
+
+    /**
+     * Check if creditmeno can be created for order
+     * @param \Magento\Sales\Model\Order $order
+     * @return bool
+     */
+    protected function _canCreditmemo($order)
+    {
+        /**
+         * Check order existing
+         */
+        if (!$order->getId()) {
+            $this->messageManager->addError(__('The order no longer exists.'));
+            return false;
+        }
+
+        /**
+         * Check creditmemo create availability
+         */
+        if (!$order->canCreditmemo()) {
+            $this->messageManager->addError(__('Cannot create credit memo for the order.'));
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * @param RequestInterface $request
+     * @param \Magento\Sales\Model\Order $order
+     * @return $this|bool
+     */
+    protected function _initInvoice(RequestInterface $request, $order)
+    {
+        $invoiceId = $request->getParam('invoice_id');
+        if ($invoiceId) {
+            $invoice = $this->invoiceFactory->create()->load(
+                $invoiceId
+            )->setOrder(
+                $order
+            );
+            if ($invoice->getId()) {
+                return $invoice;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Initialize creditmemo model instance
+     *
+     * @param RequestInterface $request
+     * @param bool $update
+     * @return \Magento\Sales\Model\Order\Creditmemo|false
+     */
+    public function load(RequestInterface $request, $update = false)
+    {
+        $creditmemo = false;
+        $creditmemoId = $request->getParam('creditmemo_id');
+        $orderId = $request->getParam('order_id');
+        if ($creditmemoId) {
+            $creditmemo = $this->creditmemoFactory->create()->load($creditmemoId);
+        } elseif ($orderId) {
+            $data = $request->getParam('creditmemo');
+            $order = $this->orderFactory->create()->load($orderId);
+            $invoice = $this->_initInvoice($request, $order);
+
+            if (!$this->_canCreditmemo($order)) {
+                return false;
+            }
+
+            $savedData = $this->_getItemData($request);
+
+            $qtys = array();
+            $backToStock = array();
+            foreach ($savedData as $orderItemId => $itemData) {
+                if (isset($itemData['qty'])) {
+                    $qtys[$orderItemId] = $itemData['qty'];
+                }
+                if (isset($itemData['back_to_stock'])) {
+                    $backToStock[$orderItemId] = true;
+                }
+            }
+            $data['qtys'] = $qtys;
+
+            $service = $this->orderServiceFactory->create(array('order' => $order));
+            if ($invoice) {
+                $creditmemo = $service->prepareInvoiceCreditmemo($invoice, $data);
+            } else {
+                $creditmemo = $service->prepareCreditmemo($data);
+            }
+
+            /**
+             * Process back to stock flags
+             */
+            foreach ($creditmemo->getAllItems() as $creditmemoItem) {
+                $orderItem = $creditmemoItem->getOrderItem();
+                $parentId = $orderItem->getParentItemId();
+                if (isset($backToStock[$orderItem->getId()])) {
+                    $creditmemoItem->setBackToStock(true);
+                } elseif ($orderItem->getParentItem() && isset($backToStock[$parentId]) && $backToStock[$parentId]) {
+                    $creditmemoItem->setBackToStock(true);
+                } elseif (empty($savedData)) {
+                    $creditmemoItem->setBackToStock(
+                        $this->inventoryHelper->isAutoReturnEnabled()
+                    );
+                } else {
+                    $creditmemoItem->setBackToStock(false);
+                }
+            }
+        }
+
+        $this->eventManager->dispatch(
+            'adminhtml_sales_order_creditmemo_register_before',
+            array('creditmemo' => $creditmemo, 'request' => $request)
+        );
+
+        $this->registry->register('current_creditmemo', $creditmemo);
+        return $creditmemo;
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemos.php
new file mode 100644
index 0000000000000000000000000000000000000000..8105be5311842e37d376c07ec3f5cd51668cd17f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Creditmemos.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Creditmemos extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Generate credit memos grid for ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initOrder();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/AddConfigured.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/AddConfigured.php
new file mode 100644
index 0000000000000000000000000000000000000000..75cc295b3f7a3de23681a9f36f6f9553ad7737c3
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/AddConfigured.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class AddConfigured extends \Magento\Sales\Controller\Adminhtml\Order\Create\AddConfigured
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..c3c7907ca67ab871ebb2ed3c6ca48dd16d293352
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Cancel.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order\Create\Cancel
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureProductToAdd.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureProductToAdd.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ada24b217a3f302c6c420180f8cf90f0bb766ac
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureProductToAdd.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class ConfigureProductToAdd extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureProductToAdd
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureQuoteItems.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureQuoteItems.php
new file mode 100644
index 0000000000000000000000000000000000000000..572a90ee510e880d9cf28f73a03237d897ce1fba
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ConfigureQuoteItems.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class ConfigureQuoteItems extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureQuoteItems
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..63be1a65da1c01ff05f3b535e1f273a4f4208b47
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Index.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create\Index
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+
+    /**
+     * Index page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Orders'));
+        $this->_title->add(__('Edit Order'));
+        $this->_view->loadLayout();
+
+        $this->_initSession()->_setActiveMenu('Magento_Sales::sales_order');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/LoadBlock.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/LoadBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec24d0818f887897ff9c85a9c9a8c71b4fa94c86
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/LoadBlock.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class LoadBlock extends \Magento\Sales\Controller\Adminhtml\Order\Create\LoadBlock
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ProcessData.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ProcessData.php
new file mode 100644
index 0000000000000000000000000000000000000000..e27ed9804eaad9857983783d5ed7065b08e1b6d4
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ProcessData.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class ProcessData extends \Magento\Sales\Controller\Adminhtml\Order\Create\ProcessData
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Reorder.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..a71f987ecd1426b163a1d35afc8a2a367fc6a387
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Reorder.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class Reorder extends \Magento\Sales\Controller\Adminhtml\Order\Create\Reorder
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6d7d2f6502b9cb8a74c4124e3c40c11680e97f2
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Save.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create\Save
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ShowUpdateResult.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a4b64fca9de6cfd19e3153d042a1ecf3d150b6d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/ShowUpdateResult.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
+
+class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create\ShowUpdateResult
+{
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Start.php
similarity index 77%
rename from app/code/Magento/Sales/Controller/Adminhtml/Order/Edit.php
rename to app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Start.php
index 83e6348af927b04d1ffcd4f29ba508f094829b79..159aff62be35630b3d381bf1187acbaa0fb5a2d4 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Edit/Start.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,21 +22,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml\Order;
+namespace Magento\Sales\Controller\Adminhtml\Order\Edit;
 
-/**
- * Adminhtml sales order edit controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Edit extends \Magento\Sales\Controller\Adminhtml\Order\Create
+class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create\Start
 {
+    /**
+     * Acl check for admin
+     *
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
+    }
+
     /**
      * Start edit order initialization
      *
      * @return void
      */
-    public function startAction()
+    public function execute()
     {
         $this->_getSession()->clearStorage();
         $orderId = $this->getRequest()->getParam('order_id');
@@ -57,29 +63,4 @@ class Edit extends \Magento\Sales\Controller\Adminhtml\Order\Create
             $this->_redirect('sales/order/view', array('order_id' => $orderId));
         }
     }
-
-    /**
-     * Index page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Orders'));
-        $this->_title->add(__('Edit Order'));
-        $this->_view->loadLayout();
-
-        $this->_initSession()->_setActiveMenu('Magento_Sales::sales_order');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Acl check for admin
-     *
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Sales::actions_edit');
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..67f5cb69004b22936530e7a8e7f8a99c9bdaf39a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/EditInterface.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+interface EditInterface extends \Magento\Framework\App\ActionInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4c23da395d872b5c8611fa0c31b1b019818da84
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Email.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Email extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Notify user
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $order->sendNewOrderEmail();
+                $historyItem = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
+                )->getUnnotifiedForInstance(
+                    $order,
+                    \Magento\Sales\Model\Order::HISTORY_ENTITY_NAME
+                );
+                if ($historyItem) {
+                    $historyItem->setIsCustomerNotified(1);
+                    $historyItem->save();
+                }
+                $this->messageManager->addSuccess(__('You sent the order email.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('We couldn\'t send the email order.'));
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+        }
+        $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportCsv.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c3d97c8a23b45db75dfa09f31062794bcf05f3b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportCsv.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class ExportCsv extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Export order grid to CSV format
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'orders.csv';
+        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.order.grid', 'grid.export');
+        return $this->_fileFactory->create($fileName, $exportBlock->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportExcel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportExcel.php
new file mode 100644
index 0000000000000000000000000000000000000000..cad39211128c6837021a355df2101c3200165c9a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ExportExcel.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class ExportExcel extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Export order grid to Excel XML format
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $fileName = 'orders.xml';
+        /** @var \Magento\Backend\Block\Widget\Grid\ExportInterface $exportBlock  */
+        $exportBlock = $this->_view->getLayout()->getChildBlock('sales.order.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $exportBlock->getExcelFile($fileName),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..e789a01526681b4f7864befeb064dc5c9c38c73e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Grid.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Order grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Hold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Hold.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b60458d5cce98a3b5c38a4e16c8b697babb7c35
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Hold.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Hold extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Hold order
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $order->hold()->save();
+                $this->messageManager->addSuccess(__('You put the order on hold.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('You have not put the order on hold.'));
+            }
+            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f5066bae6094b8e01a958c52ce6f5874fd10b00d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Orders grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Orders'));
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php
deleted file mode 100644
index ac9deb269c5eac8b2b47cddcf5804519cc180f61..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice.php
+++ /dev/null
@@ -1,496 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller\Adminhtml\Order;
-
-use Magento\Framework\Model\Exception;
-use Magento\Framework\App\ResponseInterface;
-
-/**
- * Adminhtml sales order invoice edit controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Invoice extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @var \Magento\Framework\App\Action\Title
-     */
-    protected $_title;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context, $fileFactory);
-    }
-
-    /**
-     * Get requested items qty's from request
-     *
-     * @return array
-     */
-    protected function _getItemQtys()
-    {
-        $data = $this->getRequest()->getParam('invoice');
-        if (isset($data['items'])) {
-            $qtys = $data['items'];
-        } else {
-            $qtys = array();
-        }
-        return $qtys;
-    }
-
-    /**
-     * Initialize invoice model instance
-     *
-     * @return \Magento\Sales\Model\Order\Invoice
-     * @throws \Magento\Framework\Model\Exception
-     */
-    protected function _initInvoice()
-    {
-        $this->_title->add(__('Invoices'));
-
-        $invoice = false;
-        $invoiceId = $this->getRequest()->getParam('invoice_id');
-        $orderId = $this->getRequest()->getParam('order_id');
-        if ($invoiceId) {
-            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
-            if (!$invoice->getId()) {
-                $this->messageManager->addError(__('The invoice no longer exists.'));
-                return false;
-            }
-        } elseif ($orderId) {
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-            /**
-             * Check order existing
-             */
-            if (!$order->getId()) {
-                $this->messageManager->addError(__('The order no longer exists.'));
-                return false;
-            }
-            /**
-             * Check invoice create availability
-             */
-            if (!$order->canInvoice()) {
-                $this->messageManager->addError(__('The order does not allow an invoice to be created.'));
-                return false;
-            }
-            $savedQtys = $this->_getItemQtys();
-            $invoice = $this->_objectManager->create(
-                'Magento\Sales\Model\Service\Order',
-                array('order' => $order)
-            )->prepareInvoice(
-                $savedQtys
-            );
-            if (!$invoice->getTotalQty()) {
-                throw new Exception(__('Cannot create an invoice without products.'));
-            }
-        }
-
-        $this->_coreRegistry->register('current_invoice', $invoice);
-        return $invoice;
-    }
-
-    /**
-     * Save data for invoice and related order
-     *
-     * @param   \Magento\Sales\Model\Order\Invoice $invoice
-     * @return  $this
-     */
-    protected function _saveInvoice($invoice)
-    {
-        $invoice->getOrder()->setIsInProcess(true);
-        $this->_objectManager->create(
-            'Magento\Framework\DB\Transaction'
-        )->addObject(
-            $invoice
-        )->addObject(
-            $invoice->getOrder()
-        )->save();
-
-        return $this;
-    }
-
-    /**
-     * Prepare shipment
-     *
-     * @param \Magento\Sales\Model\Order\Invoice $invoice
-     * @return \Magento\Sales\Model\Order\Shipment|false
-     */
-    protected function _prepareShipment($invoice)
-    {
-        $savedQtys = $this->_getItemQtys();
-        $shipment = $this->_objectManager->create(
-            'Magento\Sales\Model\Service\Order',
-            array('order' => $invoice->getOrder())
-        )->prepareShipment(
-            $savedQtys
-        );
-        if (!$shipment->getTotalQty()) {
-            return false;
-        }
-
-
-        $shipment->register();
-        $tracks = $this->getRequest()->getPost('tracking');
-        if ($tracks) {
-            foreach ($tracks as $data) {
-                $track = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment\Track')->addData($data);
-                $shipment->addTrack($track);
-            }
-        }
-        return $shipment;
-    }
-
-    /**
-     * Invoice information page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $invoice = $this->_initInvoice();
-        if ($invoice) {
-            $this->_title->add(sprintf("#%s", $invoice->getIncrementId()));
-
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Sales::sales_order');
-            $this->_view->getLayout()->getBlock(
-                'sales_invoice_view'
-            )->updateBackButtonUrl(
-                $this->getRequest()->getParam('come_from')
-            );
-            $this->_view->renderLayout();
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Start create invoice action
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        /**
-         * Clear old values for invoice qty's
-         */
-        $this->_getSession()->getInvoiceItemQtys(true);
-        $this->_redirect('sales/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
-    }
-
-    /**
-     * Invoice create page
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $invoice = $this->_initInvoice();
-        if ($invoice) {
-            $this->_title->add(__('New Invoice'));
-
-            $comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
-            if ($comment) {
-                $invoice->setCommentText($comment);
-            }
-
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Sales::sales_order');
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('sales/order/view', array('order_id' => $this->getRequest()->getParam('order_id')));
-        }
-    }
-
-    /**
-     * Update items qty action
-     *
-     * @return void
-     */
-    public function updateQtyAction()
-    {
-        try {
-            $invoice = $this->_initInvoice(true);
-            // Save invoice comment text in current invoice object in order to display it in corresponding view
-            $invoiceRawData = $this->getRequest()->getParam('invoice');
-            $invoiceRawCommentText = $invoiceRawData['comment_text'];
-            $invoice->setCommentText($invoiceRawCommentText);
-
-            $this->_view->loadLayout();
-            $response = $this->_view->getLayout()->getBlock('order_items')->toHtml();
-        } catch (Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot update item quantity.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Save invoice
-     * We can save only new invoice. Existing invoices are not editable
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost('invoice');
-        $orderId = $this->getRequest()->getParam('order_id');
-
-        if (!empty($data['comment_text'])) {
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setCommentText($data['comment_text']);
-        }
-
-        try {
-            $invoice = $this->_initInvoice();
-            if ($invoice) {
-
-                if (!empty($data['capture_case'])) {
-                    $invoice->setRequestedCaptureCase($data['capture_case']);
-                }
-
-                if (!empty($data['comment_text'])) {
-                    $invoice->addComment(
-                        $data['comment_text'],
-                        isset($data['comment_customer_notify']),
-                        isset($data['is_visible_on_front'])
-                    );
-                }
-
-                $invoice->register();
-
-                if (!empty($data['send_email'])) {
-                    $invoice->setEmailSent(true);
-                }
-
-                $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
-                $invoice->getOrder()->setIsInProcess(true);
-
-                $transactionSave = $this->_objectManager->create(
-                    'Magento\Framework\DB\Transaction'
-                )->addObject(
-                    $invoice
-                )->addObject(
-                    $invoice->getOrder()
-                );
-                $shipment = false;
-                if (!empty($data['do_shipment']) || (int)$invoice->getOrder()->getForcedShipmentWithInvoice()) {
-                    $shipment = $this->_prepareShipment($invoice);
-                    if ($shipment) {
-                        $shipment->setEmailSent($invoice->getEmailSent());
-                        $transactionSave->addObject($shipment);
-                    }
-                }
-                $transactionSave->save();
-
-                if (isset($shippingResponse) && $shippingResponse->hasErrors()) {
-                    $this->messageManager->addError(
-                        __(
-                            'The invoice and the shipment  have been created. ' .
-                            'The shipping label cannot be created now.'
-                        )
-                    );
-                } elseif (!empty($data['do_shipment'])) {
-                    $this->messageManager->addSuccess(__('You created the invoice and shipment.'));
-                } else {
-                    $this->messageManager->addSuccess(__('The invoice has been created.'));
-                }
-
-                // send invoice/shipment emails
-                $comment = '';
-                if (isset($data['comment_customer_notify'])) {
-                    $comment = $data['comment_text'];
-                }
-                try {
-                    $invoice->sendEmail(!empty($data['send_email']), $comment);
-                } catch (\Exception $e) {
-                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                    $this->messageManager->addError(__('We can\'t send the invoice email.'));
-                }
-                if ($shipment) {
-                    try {
-                        $shipment->sendEmail(!empty($data['send_email']));
-                    } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                        $this->messageManager->addError(__('We can\'t send the shipment.'));
-                    }
-                }
-                $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
-                $this->_redirect('sales/order/view', array('order_id' => $orderId));
-            } else {
-                $this->_redirect('sales/*/new', array('order_id' => $orderId));
-            }
-            return;
-        } catch (Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t save the invoice.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('sales/*/new', array('order_id' => $orderId));
-    }
-
-    /**
-     * Capture invoice action
-     *
-     * @return void
-     */
-    public function captureAction()
-    {
-        $invoice = $this->_initInvoice();
-        if ($invoice) {
-            try {
-                $invoice->capture();
-                $this->_saveInvoice($invoice);
-                $this->messageManager->addSuccess(__('The invoice has been captured.'));
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Invoice capturing error'));
-            }
-            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Cancel invoice action
-     *
-     * @return void
-     */
-    public function cancelAction()
-    {
-        $invoice = $this->_initInvoice();
-        if ($invoice) {
-            try {
-                $invoice->cancel();
-                $this->_saveInvoice($invoice);
-                $this->messageManager->addSuccess(__('You canceled the invoice.'));
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Invoice canceling error'));
-            }
-            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Void invoice action
-     *
-     * @return void
-     */
-    public function voidAction()
-    {
-        $invoice = $this->_initInvoice();
-        if ($invoice) {
-            try {
-                $invoice->void();
-                $this->_saveInvoice($invoice);
-                $this->messageManager->addSuccess(__('The invoice has been voided.'));
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Invoice voiding error'));
-            }
-            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Add comment to invoice action
-     *
-     * @return void
-     */
-    public function addCommentAction()
-    {
-        try {
-            $this->getRequest()->setParam('invoice_id', $this->getRequest()->getParam('id'));
-            $data = $this->getRequest()->getPost('comment');
-            if (empty($data['comment'])) {
-                throw new Exception(__('The Comment Text field cannot be empty.'));
-            }
-            $invoice = $this->_initInvoice();
-            $invoice->addComment(
-                $data['comment'],
-                isset($data['is_customer_notified']),
-                isset($data['is_visible_on_front'])
-            );
-            $invoice->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
-            $invoice->save();
-
-            $this->_view->loadLayout();
-            $response = $this->_view->getLayout()->getBlock('invoice_comments')->toHtml();
-        } catch (Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Create pdf for current invoice
-     *
-     * @return ResponseInterface|void
-     */
-    public function printAction()
-    {
-        $this->_initInvoice();
-        parent::printAction();
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/AddComment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/AddComment.php
new file mode 100644
index 0000000000000000000000000000000000000000..af6483eebe374e1f9cfdeda34756348a64d7662a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/AddComment.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use Magento\Backend\App\Action;
+use \Magento\Framework\Model\Exception;
+
+class AddComment extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Add comment to invoice action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getRequest()->setParam('invoice_id', $this->getRequest()->getParam('id'));
+            $data = $this->getRequest()->getPost('comment');
+            if (empty($data['comment'])) {
+                throw new Exception(__('The Comment Text field cannot be empty.'));
+            }
+            $this->_title->add(__('Invoices'));
+            $invoice = $this->invoiceLoader->load($this->_request);
+            $invoice->addComment(
+                $data['comment'],
+                isset($data['is_customer_notified']),
+                isset($data['is_visible_on_front'])
+            );
+            $invoice->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
+            $invoice->save();
+
+            $this->_view->loadLayout();
+            $response = $this->_view->getLayout()->getBlock('invoice_comments')->toHtml();
+        } catch (Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Cancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e165a80a6db4cf651878860dd6133af2a25d523
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Cancel.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use \Magento\Framework\Model\Exception;
+use Magento\Backend\App\Action;
+
+class Cancel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Cancel invoice action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $invoice = $this->invoiceLoader->load($this->_request);
+        if ($invoice) {
+            try {
+                $invoice->cancel();
+                $invoice->getOrder()->setIsInProcess(true);
+                $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $invoice
+                )->addObject(
+                    $invoice->getOrder()
+                )->save();
+                $this->messageManager->addSuccess(__('You canceled the invoice.'));
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Invoice canceling error'));
+            }
+            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Capture.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Capture.php
new file mode 100644
index 0000000000000000000000000000000000000000..55b222ed897812742a9ebadcaed501ab3a6b4e56
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Capture.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use \Magento\Framework\Model\Exception;
+use Magento\Backend\App\Action;
+
+class Capture extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Capture invoice action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $invoice = $this->invoiceLoader->load($this->_request);
+        if ($invoice) {
+            try {
+                $invoice->capture();
+                $invoice->getOrder()->setIsInProcess(true);
+                $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $invoice
+                )->addObject(
+                    $invoice->getOrder()
+                )->save();
+                $this->messageManager->addSuccess(__('The invoice has been captured.'));
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Invoice capturing error'));
+            }
+            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Email.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ed1e07bb945cd7e3d23a3eb8f9302f4215750a4
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Email.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+class Email extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Email
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..19795844615a2e9bc1d866434c6c938ec6af98bb
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Grid.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Grid
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..3bd86a6f472f90997251edbe39c2d8fcc8dc936b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Index
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..32aebbaae6e37997c14970618e9cf5f96a081a0c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/NewAction.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use Magento\Backend\App\Action;
+
+class NewAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Invoice create page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Invoices'));
+        $invoice = $this->invoiceLoader->load($this->_request);
+        if ($invoice) {
+            $this->_title->add(__('New Invoice'));
+
+            $comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
+            if ($comment) {
+                $invoice->setCommentText($comment);
+            }
+
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Sales::sales_order');
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('sales/order/view', array('order_id' => $this->getRequest()->getParam('order_id')));
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Pdfinvoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Pdfinvoices.php
new file mode 100644
index 0000000000000000000000000000000000000000..c42f4aaeb21e81a2aff03575ad6b735473227cd7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Pdfinvoices.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\Pdfinvoices
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1648c406af95c56c348337903a0a83e80c74eec
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/PrintAction.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use Magento\Backend\App\Action;
+use \Magento\Framework\App\ResponseInterface;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\PrintAction
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context, $fileFactory);
+    }
+
+    /**
+     * Create pdf for current invoice
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $this->invoiceLoader->load($this->_request);
+        parent::execute();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..9b08f15f3e843b88beb039f01b8c14863a2078ea
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Save.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use \Magento\Framework\Model\Exception;
+use Magento\Backend\App\Action;
+
+class Save extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Prepare shipment
+     *
+     * @param \Magento\Sales\Model\Order\Invoice $invoice
+     * @return \Magento\Sales\Model\Order\Shipment|false
+     */
+    protected function _prepareShipment($invoice)
+    {
+        $savedQtys = array();
+        $data = $this->getRequest()->getParam('invoice');
+        if (isset($data['items'])) {
+            $savedQtys = $data['items'];
+        }
+        $shipment = $this->_objectManager->create(
+            'Magento\Sales\Model\Service\Order',
+            array('order' => $invoice->getOrder())
+        )->prepareShipment(
+            $savedQtys
+        );
+        if (!$shipment->getTotalQty()) {
+            return false;
+        }
+
+        $shipment->register();
+        $tracks = $this->getRequest()->getPost('tracking');
+        if ($tracks) {
+            foreach ($tracks as $data) {
+                $track = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment\Track')->addData($data);
+                $shipment->addTrack($track);
+            }
+        }
+        return $shipment;
+    }
+
+    /**
+     * Save invoice
+     * We can save only new invoice. Existing invoices are not editable
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost('invoice');
+        $orderId = $this->getRequest()->getParam('order_id');
+
+        if (!empty($data['comment_text'])) {
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setCommentText($data['comment_text']);
+        }
+
+        try {
+            $invoice = $this->invoiceLoader->load($this->_request);
+            if ($invoice) {
+
+                if (!empty($data['capture_case'])) {
+                    $invoice->setRequestedCaptureCase($data['capture_case']);
+                }
+
+                if (!empty($data['comment_text'])) {
+                    $invoice->addComment(
+                        $data['comment_text'],
+                        isset($data['comment_customer_notify']),
+                        isset($data['is_visible_on_front'])
+                    );
+                }
+
+                $invoice->register();
+
+                if (!empty($data['send_email'])) {
+                    $invoice->setEmailSent(true);
+                }
+
+                $invoice->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
+                $invoice->getOrder()->setIsInProcess(true);
+
+                $transactionSave = $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $invoice
+                )->addObject(
+                    $invoice->getOrder()
+                );
+                $shipment = false;
+                if (!empty($data['do_shipment']) || (int)$invoice->getOrder()->getForcedShipmentWithInvoice()) {
+                    $shipment = $this->_prepareShipment($invoice);
+                    if ($shipment) {
+                        $shipment->setEmailSent($invoice->getEmailSent());
+                        $transactionSave->addObject($shipment);
+                    }
+                }
+                $transactionSave->save();
+
+                if (isset($shippingResponse) && $shippingResponse->hasErrors()) {
+                    $this->messageManager->addError(
+                        __(
+                            'The invoice and the shipment  have been created. ' .
+                            'The shipping label cannot be created now.'
+                        )
+                    );
+                } elseif (!empty($data['do_shipment'])) {
+                    $this->messageManager->addSuccess(__('You created the invoice and shipment.'));
+                } else {
+                    $this->messageManager->addSuccess(__('The invoice has been created.'));
+                }
+
+                // send invoice/shipment emails
+                $comment = '';
+                if (isset($data['comment_customer_notify'])) {
+                    $comment = $data['comment_text'];
+                }
+                try {
+                    $invoice->sendEmail(!empty($data['send_email']), $comment);
+                } catch (\Exception $e) {
+                    $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                    $this->messageManager->addError(__('We can\'t send the invoice email.'));
+                }
+                if ($shipment) {
+                    try {
+                        $shipment->sendEmail(!empty($data['send_email']));
+                    } catch (\Exception $e) {
+                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                        $this->messageManager->addError(__('We can\'t send the shipment.'));
+                    }
+                }
+                $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
+                $this->_redirect('sales/order/view', array('order_id' => $orderId));
+            } else {
+                $this->_redirect('sales/*/new', array('order_id' => $orderId));
+            }
+            return;
+        } catch (Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t save the invoice.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('sales/*/new', array('order_id' => $orderId));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..760f1c94a900978be4e5d4dd31a282586c6a6ec3
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Start.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+class Start extends \Magento\Backend\App\Action
+{
+    /**
+     * Start create invoice action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /**
+         * Clear old values for invoice qty's
+         */
+        $this->_getSession()->getInvoiceItemQtys(true);
+        $this->_redirect('sales/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php
new file mode 100644
index 0000000000000000000000000000000000000000..00a2a80336c5c53fd12e651777ba045e66e08e1f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/UpdateQty.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use \Magento\Framework\Model\Exception;
+use Magento\Backend\App\Action;
+
+class UpdateQty extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Update items qty action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_title->add(__('Invoices'));
+            $invoice = $this->invoiceLoader->load($this->_request);
+            // Save invoice comment text in current invoice object in order to display it in corresponding view
+            $invoiceRawData = $this->getRequest()->getParam('invoice');
+            $invoiceRawCommentText = $invoiceRawData['comment_text'];
+            $invoice->setCommentText($invoiceRawCommentText);
+
+            $this->_view->loadLayout();
+            $response = $this->_view->getLayout()->getBlock('order_items')->toHtml();
+        } catch (Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot update item quantity.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..866560925d7f3dcb6cfd92a1c2312b1563dfd512
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/View.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use Magento\Backend\App\Action;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Invoice\AbstractInvoice\View
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * Invoice information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Invoices'));
+        $invoice = $this->invoiceLoader->load($this->_request);
+        if ($invoice) {
+            $this->_title->add(sprintf("#%s", $invoice->getIncrementId()));
+
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Sales::sales_order');
+            $this->_view->getLayout()->getBlock(
+                'sales_invoice_view'
+            )->updateBackButtonUrl(
+                $this->getRequest()->getParam('come_from')
+            );
+            $this->_view->renderLayout();
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Void.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Void.php
new file mode 100644
index 0000000000000000000000000000000000000000..6b1e153ea88037c27c9084d74a1b17c2d53231bb
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoice/Void.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Invoice;
+
+use \Magento\Framework\Model\Exception;
+use Magento\Backend\App\Action;
+
+class Void extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader
+     */
+    protected $invoiceLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Sales\Controller\Adminhtml\Order\InvoiceLoader $invoiceLoader
+    ) {
+        $this->invoiceLoader = $invoiceLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::sales_invoice');
+    }
+
+    /**
+     * Void invoice action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $invoice = $this->invoiceLoader->load($this->_request);
+        if ($invoice) {
+            try {
+                $invoice->void();
+                $invoice->getOrder()->setIsInProcess(true);
+                $this->_objectManager->create(
+                    'Magento\Framework\DB\Transaction'
+                )->addObject(
+                    $invoice
+                )->addObject(
+                    $invoice->getOrder()
+                )->save();
+                $this->messageManager->addSuccess(__('The invoice has been voided.'));
+            } catch (Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Invoice voiding error'));
+            }
+            $this->_redirect('sales/*/view', array('invoice_id' => $invoice->getId()));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/InvoiceLoader.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/InvoiceLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9e0f00dce56da2f4467d61cbf4ece7690815e46
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/InvoiceLoader.php
@@ -0,0 +1,115 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use Magento\Framework\App\RequestInterface;
+
+class InvoiceLoader
+{
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $_objectManager;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @param \Magento\Framework\ObjectManager $objectManager
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManager $objectManager,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\Message\ManagerInterface $messageManager
+    ) {
+        $this->messageManager = $messageManager;
+        $this->registry = $registry;
+        $this->_objectManager = $objectManager;
+    }
+
+    /**
+     * Load invoice
+     *
+     * @param RequestInterface $request
+     * @return bool
+     * @throws \Exception
+     */
+    public function load(RequestInterface $request)
+    {
+        $invoice = false;
+        $invoiceId = $request->getParam('invoice_id');
+        $orderId = $request->getParam('order_id');
+        if ($invoiceId) {
+            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
+            if (!$invoice->getId()) {
+                $this->messageManager->addError(__('The invoice no longer exists.'));
+                return false;
+            }
+        } elseif ($orderId) {
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+            /**
+             * Check order existing
+             */
+            if (!$order->getId()) {
+                $this->messageManager->addError(__('The order no longer exists.'));
+                return false;
+            }
+            /**
+             * Check invoice create availability
+             */
+            if (!$order->canInvoice()) {
+                $this->messageManager->addError(__('The order does not allow an invoice to be created.'));
+                return false;
+            }
+            $savedQtys = array();
+            $data = $request->getParam('invoice');
+            if (isset($data['items'])) {
+                $savedQtys = $data['items'];
+            }
+
+            $invoice = $this->_objectManager->create(
+                'Magento\Sales\Model\Service\Order',
+                array('order' => $order)
+            )->prepareInvoice(
+                $savedQtys
+            );
+            if (!$invoice->getTotalQty()) {
+                throw new \Exception(__('Cannot create an invoice without products.'));
+            }
+        }
+
+        $this->registry->register('current_invoice', $invoice);
+        return $invoice;
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoices.php
new file mode 100644
index 0000000000000000000000000000000000000000..2588cab75eea80bef34d5911ee3241d8d24e9c56
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Invoices.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Invoices extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Generate invoices grid for ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initOrder();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..50f1bb24651eef83a7a1cd589a7424072d190fba
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassCancel.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class MassCancel extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Cancel selected orders
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids', array());
+        $countCancelOrder = 0;
+        $countNonCancelOrder = 0;
+        foreach ($orderIds as $orderId) {
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+            if ($order->canCancel()) {
+                $order->cancel()->save();
+                $countCancelOrder++;
+            } else {
+                $countNonCancelOrder++;
+            }
+        }
+        if ($countNonCancelOrder) {
+            if ($countCancelOrder) {
+                $this->messageManager->addError(__('%1 order(s) cannot be canceled.', $countNonCancelOrder));
+            } else {
+                $this->messageManager->addError(__('You cannot cancel the order(s).'));
+            }
+        }
+        if ($countCancelOrder) {
+            $this->messageManager->addSuccess(__('We canceled %1 order(s).', $countCancelOrder));
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php
new file mode 100644
index 0000000000000000000000000000000000000000..180eaa42cc9e20c90a4b95cb942d72469ecfa448
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassHold.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class MassHold extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Hold selected orders
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids', array());
+        $countHoldOrder = 0;
+
+        foreach ($orderIds as $orderId) {
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+            if ($order->canHold()) {
+                $order->hold()->save();
+                $countHoldOrder++;
+            }
+        }
+
+        $countNonHoldOrder = count($orderIds) - $countHoldOrder;
+
+        if ($countNonHoldOrder) {
+            if ($countHoldOrder) {
+                $this->messageManager->addError(__('%1 order(s) were not put on hold.', $countNonHoldOrder));
+            } else {
+                $this->messageManager->addError(__('No order(s) were put on hold.'));
+            }
+        }
+        if ($countHoldOrder) {
+            $this->messageManager->addSuccess(__('You have put %1 order(s) on hold.', $countHoldOrder));
+        }
+
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassPrint.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassPrint.php
new file mode 100644
index 0000000000000000000000000000000000000000..20b71d282b309b0601be320d9074e091ca0e0ef1
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassPrint.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class MassPrint extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Print documents for selected orders
+     *
+     * @return void
+     */
+    public function execute()
+    {
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassStatus.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassStatus.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce8dca6dfe73cc4d0f50887e46586fcaa0ac02bf
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassStatus.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class MassStatus extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Change status for selected orders
+     *
+     * @return void
+     */
+    public function execute()
+    {
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce5ff1054ca49265eee5d1686cf51687651ac571
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/MassUnhold.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class MassUnhold extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Unhold selected orders
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids', array());
+        $countUnHoldOrder = 0;
+        $countNonUnHoldOrder = 0;
+
+        foreach ($orderIds as $orderId) {
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
+            if ($order->canUnhold()) {
+                $order->unhold()->save();
+                $countUnHoldOrder++;
+            } else {
+                $countNonUnHoldOrder++;
+            }
+        }
+        if ($countNonUnHoldOrder) {
+            if ($countUnHoldOrder) {
+                $this->messageManager->addError(
+                    __('%1 order(s) were not released from on hold status.', $countNonUnHoldOrder)
+                );
+            } else {
+                $this->messageManager->addError(__('No order(s) were released from on hold status.'));
+            }
+        }
+        if ($countUnHoldOrder) {
+            $this->messageManager->addSuccess(
+                __('%1 order(s) have been released from on hold status.', $countUnHoldOrder)
+            );
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php
new file mode 100644
index 0000000000000000000000000000000000000000..33c6f6b5e342d7291ed7270c118cb0d681da45fe
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfcreditmemos.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class Pdfcreditmemos extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Print credit memos for selected orders
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids');
+        $flag = false;
+        if (!empty($orderIds)) {
+            foreach ($orderIds as $orderId) {
+                $creditmemos = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($creditmemos->getSize()) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
+                        )->getPdf(
+                            $creditmemos
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
+                        )->getPdf(
+                            $creditmemos
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+            }
+            if ($flag) {
+                return $this->_fileFactory->create(
+                    'creditmemo' . $this->_objectManager->get(
+                        'Magento\Framework\Stdlib\DateTime\DateTime'
+                    )->date(
+                        'Y-m-d_H-i-s'
+                    ) . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            } else {
+                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
+                $this->_redirect('sales/*/');
+            }
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfdocs.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfdocs.php
new file mode 100644
index 0000000000000000000000000000000000000000..451454184fdc31ad080db666339be8892b09f9cc
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfdocs.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class Pdfdocs extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Print all documents for selected orders
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids');
+        $flag = false;
+        if (!empty($orderIds)) {
+            foreach ($orderIds as $orderId) {
+                $invoices = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Invoice\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($invoices->getSize()) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Invoice'
+                        )->getPdf(
+                            $invoices
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Invoice'
+                        )->getPdf(
+                            $invoices
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+
+                $shipments = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Shipment\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($shipments->getSize()) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Shipment'
+                        )->getPdf(
+                            $shipments
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Shipment'
+                        )->getPdf(
+                            $shipments
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+
+                $creditmemos = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Creditmemo\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($creditmemos->getSize()) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
+                        )->getPdf(
+                            $creditmemos
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Creditmemo'
+                        )->getPdf(
+                            $creditmemos
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+            }
+            if ($flag) {
+                return $this->_fileFactory->create(
+                    'docs' . $this->_objectManager->get(
+                        'Magento\Framework\Stdlib\DateTime\DateTime'
+                    )->date(
+                        'Y-m-d_H-i-s'
+                    ) . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            } else {
+                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
+                $this->_redirect('sales/*/');
+            }
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php
new file mode 100644
index 0000000000000000000000000000000000000000..aa64ce9146b74dd37d22a7459fea09fe495886f2
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfinvoices.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class Pdfinvoices extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Print invoices for selected orders
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids');
+        $flag = false;
+        if (!empty($orderIds)) {
+            foreach ($orderIds as $orderId) {
+                $invoices = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Invoice\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($invoices->getSize() > 0) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Invoice'
+                        )->getPdf(
+                            $invoices
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Invoice'
+                        )->getPdf(
+                            $invoices
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+            }
+            if ($flag) {
+                return $this->_fileFactory->create(
+                    'invoice' . $this->_objectManager->get(
+                        'Magento\Framework\Stdlib\DateTime\DateTime'
+                    )->date(
+                        'Y-m-d_H-i-s'
+                    ) . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            } else {
+                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
+                $this->_redirect('sales/*/');
+            }
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfshipments.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfshipments.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5c28bceb75b38829c5cd58fbb96fe8d96b62609
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Pdfshipments.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class Pdfshipments extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Print shipments for selected orders
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $orderIds = $this->getRequest()->getPost('order_ids');
+        $flag = false;
+        if (!empty($orderIds)) {
+            foreach ($orderIds as $orderId) {
+                $shipments = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Shipment\Collection'
+                )->setOrderFilter(
+                    $orderId
+                )->load();
+                if ($shipments->getSize()) {
+                    $flag = true;
+                    if (!isset($pdf)) {
+                        $pdf = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Shipment'
+                        )->getPdf(
+                            $shipments
+                        );
+                    } else {
+                        $pages = $this->_objectManager->create(
+                            'Magento\Sales\Model\Order\Pdf\Shipment'
+                        )->getPdf(
+                            $shipments
+                        );
+                        $pdf->pages = array_merge($pdf->pages, $pages->pages);
+                    }
+                }
+            }
+            if ($flag) {
+                return $this->_fileFactory->create(
+                    'packingslip' . $this->_objectManager->get(
+                        'Magento\Framework\Stdlib\DateTime\DateTime'
+                    )->date(
+                        'Y-m-d_H-i-s'
+                    ) . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            } else {
+                $this->messageManager->addError(__('There are no printable documents related to selected orders.'));
+                $this->_redirect('sales/*/');
+            }
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ea334881531a54fdff067372df9ff14713fd7fc
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class ReviewPayment extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Manage payment state
+     *
+     * Either denies or approves a payment that is in "review" state
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $order = $this->_initOrder();
+            if (!$order) {
+                return;
+            }
+            $action = $this->getRequest()->getParam('action', '');
+            switch ($action) {
+                case 'accept':
+                    $order->getPayment()->accept();
+                    $message = __('The payment has been accepted.');
+                    break;
+                case 'deny':
+                    $order->getPayment()->deny();
+                    $message = __('The payment has been denied.');
+                    break;
+                case 'update':
+                    $order->getPayment()->registerPaymentReviewAction(
+                        \Magento\Sales\Model\Order\Payment::REVIEW_ACTION_UPDATE,
+                        true
+                    );
+                    $message = __('The payment update has been made.');
+                    break;
+                default:
+                    throw new \Exception(sprintf('Action "%s" is not supported.', $action));
+            }
+            $order->save();
+            $this->messageManager->addSuccess($message);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We couldn\'t update the payment.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Shipments.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Shipments.php
new file mode 100644
index 0000000000000000000000000000000000000000..df8a08e70a2101f69f529f8bc30e65b9bd3e3158
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Shipments.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Shipments extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Generate shipments grid for ajax request
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initOrder();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status.php
index 4637f63a949ac65b3195b1f46cdf230261c3e3d1..080ced08e465d4bb76d05882653b5af56e6c33a5 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status.php
@@ -63,193 +63,6 @@ class Status extends \Magento\Backend\App\Action
         return $status;
     }
 
-    /**
-     * Statuses grid page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Order Status'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * New status form
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $data = $this->_getSession()->getFormData(true);
-        if ($data) {
-            $status = $this->_objectManager->create('Magento\Sales\Model\Order\Status')->setData($data);
-            $this->_coreRegistry->register('current_status', $status);
-        }
-        $this->_title->add(__('Order Status'));
-        $this->_title->add(__('Create New Order Status'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Editing existing status form
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $status = $this->_initStatus();
-        if ($status) {
-            $this->_coreRegistry->register('current_status', $status);
-            $this->_title->add(__('Order Status'));
-            $this->_title->add(__('Edit Order Status'));
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Sales::system_order_statuses');
-            $this->_view->renderLayout();
-        } else {
-            $this->messageManager->addError(__('We can\'t find this order status.'));
-            $this->_redirect('sales/');
-        }
-    }
-
-    /**
-     * Save status form processing
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost();
-        $isNew = $this->getRequest()->getParam('is_new');
-        if ($data) {
-
-            $statusCode = $this->getRequest()->getParam('status');
-
-            //filter tags in labels/status
-            /** @var $filterManager \Magento\Framework\Filter\FilterManager */
-            $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
-            if ($isNew) {
-                $statusCode = $data['status'] = $filterManager->stripTags($data['status']);
-            }
-            $data['label'] = $filterManager->stripTags($data['label']);
-            foreach ($data['store_labels'] as &$label) {
-                $label = $filterManager->stripTags($label);
-            }
-
-            $status = $this->_objectManager->create('Magento\Sales\Model\Order\Status')->load($statusCode);
-            // check if status exist
-            if ($isNew && $status->getStatus()) {
-                $this->messageManager->addError(__('We found another order status with the same order status code.'));
-                $this->_getSession()->setFormData($data);
-                $this->_redirect('sales/*/new');
-                return;
-            }
-
-            $status->setData($data)->setStatus($statusCode);
-
-            try {
-                $status->save();
-                $this->messageManager->addSuccess(__('You have saved the order status.'));
-                $this->_redirect('sales/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('We couldn\'t add your order status because something went wrong saving.')
-                );
-            }
-            $this->_getSession()->setFormData($data);
-            if ($isNew) {
-                $this->_redirect('sales/*/new');
-            } else {
-                $this->_redirect('sales/*/edit', array('status' => $this->getRequest()->getParam('status')));
-            }
-            return;
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * Assign status to state form
-     *
-     * @return void
-     */
-    public function assignAction()
-    {
-        $this->_title->add(__('Order Status'));
-        $this->_title->add(__('Assign Order Status to State'));
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save status assignment to state
-     *
-     * @return void
-     */
-    public function assignPostAction()
-    {
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            $state = $this->getRequest()->getParam('state');
-            $isDefault = $this->getRequest()->getParam('is_default');
-            $visibleOnFront = $this->getRequest()->getParam('visible_on_front');
-            $status = $this->_initStatus();
-            if ($status && $status->getStatus()) {
-                try {
-                    $status->assignState($state, $isDefault, $visibleOnFront);
-                    $this->messageManager->addSuccess(__('You have assigned the order status.'));
-                    $this->_redirect('sales/*/');
-                    return;
-                } catch (\Magento\Framework\Model\Exception $e) {
-                    $this->messageManager->addError($e->getMessage());
-                } catch (\Exception $e) {
-                    $this->messageManager->addException(
-                        $e,
-                        __('An error occurred while assigning order status. Status has not been assigned.')
-                    );
-                }
-            } else {
-                $this->messageManager->addError(__('We can\'t find this order status.'));
-            }
-            $this->_redirect('sales/*/assign');
-            return;
-        }
-        $this->_redirect('sales/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function unassignAction()
-    {
-        $state = $this->getRequest()->getParam('state');
-        $status = $this->_initStatus();
-        if ($status) {
-            try {
-                $status->unassignState($state);
-                $this->messageManager->addSuccess(__('You have unassigned the order status.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException(
-                    $e,
-                    __('Something went wrong while we were unassigning the order.')
-                );
-            }
-        } else {
-            $this->messageManager->addError(__('We can\'t find this order status.'));
-        }
-        $this->_redirect('sales/*/');
-    }
-
     /**
      * Check current user permission on resource and privilege
      *
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php
new file mode 100644
index 0000000000000000000000000000000000000000..fdf5bacdfe870dcc76afec49045a37cbc06739b2
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Assign.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class Assign extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * Assign status to state form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Order Status'));
+        $this->_title->add(__('Assign Order Status to State'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..f454c9d99614d0eb109dffd15b659105d9f868a7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/AssignPost.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class AssignPost extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * Save status assignment to state
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            $state = $this->getRequest()->getParam('state');
+            $isDefault = $this->getRequest()->getParam('is_default');
+            $visibleOnFront = $this->getRequest()->getParam('visible_on_front');
+            $status = $this->_initStatus();
+            if ($status && $status->getStatus()) {
+                try {
+                    $status->assignState($state, $isDefault, $visibleOnFront);
+                    $this->messageManager->addSuccess(__('You have assigned the order status.'));
+                    $this->_redirect('sales/*/');
+                    return;
+                } catch (\Magento\Framework\Model\Exception $e) {
+                    $this->messageManager->addError($e->getMessage());
+                } catch (\Exception $e) {
+                    $this->messageManager->addException(
+                        $e,
+                        __('An error occurred while assigning order status. Status has not been assigned.')
+                    );
+                }
+            } else {
+                $this->messageManager->addError(__('We can\'t find this order status.'));
+            }
+            $this->_redirect('sales/*/assign');
+            return;
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Edit.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..031d20dfe5804dabc4cb513bb3379a9d16e47fcd
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Edit.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class Edit extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * Editing existing status form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $status = $this->_initStatus();
+        if ($status) {
+            $this->_coreRegistry->register('current_status', $status);
+            $this->_title->add(__('Order Status'));
+            $this->_title->add(__('Edit Order Status'));
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Sales::system_order_statuses');
+            $this->_view->renderLayout();
+        } else {
+            $this->messageManager->addError(__('We can\'t find this order status.'));
+            $this->_redirect('sales/');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..931493407a8ba386c75272dd905919f0b8bb64ac
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * Statuses grid page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Order Status'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/NewAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..865afc23c12c1798b64b4d9d11ce13ab224dbbe6
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/NewAction.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class NewAction extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * New status form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->_getSession()->getFormData(true);
+        if ($data) {
+            $status = $this->_objectManager->create('Magento\Sales\Model\Order\Status')->setData($data);
+            $this->_coreRegistry->register('current_status', $status);
+        }
+        $this->_title->add(__('Order Status'));
+        $this->_title->add(__('Create New Order Status'));
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Sales::system_order_statuses');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..061e63c6ad4b609b6a04c29b88db45285f44e763
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Save.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * Save status form processing
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost();
+        $isNew = $this->getRequest()->getParam('is_new');
+        if ($data) {
+
+            $statusCode = $this->getRequest()->getParam('status');
+
+            //filter tags in labels/status
+            /** @var $filterManager \Magento\Framework\Filter\FilterManager */
+            $filterManager = $this->_objectManager->get('Magento\Framework\Filter\FilterManager');
+            if ($isNew) {
+                $statusCode = $data['status'] = $filterManager->stripTags($data['status']);
+            }
+            $data['label'] = $filterManager->stripTags($data['label']);
+            foreach ($data['store_labels'] as &$label) {
+                $label = $filterManager->stripTags($label);
+            }
+
+            $status = $this->_objectManager->create('Magento\Sales\Model\Order\Status')->load($statusCode);
+            // check if status exist
+            if ($isNew && $status->getStatus()) {
+                $this->messageManager->addError(__('We found another order status with the same order status code.'));
+                $this->_getSession()->setFormData($data);
+                $this->_redirect('sales/*/new');
+                return;
+            }
+
+            $status->setData($data)->setStatus($statusCode);
+
+            try {
+                $status->save();
+                $this->messageManager->addSuccess(__('You have saved the order status.'));
+                $this->_redirect('sales/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('We couldn\'t add your order status because something went wrong saving.')
+                );
+            }
+            $this->_getSession()->setFormData($data);
+            if ($isNew) {
+                $this->_redirect('sales/*/new');
+            } else {
+                $this->_redirect('sales/*/edit', array('status' => $this->getRequest()->getParam('status')));
+            }
+            return;
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf0093b5bffe34e96997e4676ca87a4ee63ae58a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Status/Unassign.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\Status;
+
+class Unassign extends \Magento\Sales\Controller\Adminhtml\Order\Status
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $state = $this->getRequest()->getParam('state');
+        $status = $this->_initStatus();
+        if ($status) {
+            try {
+                $status->unassignState($state);
+                $this->messageManager->addSuccess(__('You have unassigned the order status.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException(
+                    $e,
+                    __('Something went wrong while we were unassigning the order.')
+                );
+            }
+        } else {
+            $this->messageManager->addError(__('We can\'t find this order status.'));
+        }
+        $this->_redirect('sales/*/');
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Transactions.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Transactions.php
new file mode 100644
index 0000000000000000000000000000000000000000..6035c649c255c20bad0863c3a6881d13f1017325
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Transactions.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Transactions extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Order transactions grid ajax action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initOrder();
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/Unhold.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/Unhold.php
new file mode 100644
index 0000000000000000000000000000000000000000..537d904fb3d78af789f7146691c914c8c33326eb
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/Unhold.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class Unhold extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Unhold order
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $order->unhold()->save();
+                $this->messageManager->addSuccess(__('You released the order from holding status.'));
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('The order was not on hold.'));
+            }
+            $this->_redirect('sales/order/view', array('order_id' => $order->getId()));
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfb44146d7e0d0afd26f820812325aa3689643e3
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/View.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * View order detail
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Orders'));
+
+        $order = $this->_initOrder();
+        if ($order) {
+            try {
+                $this->_initAction();
+            } catch (\Magento\Framework\App\Action\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('sales/order/index');
+                return;
+            } catch (\Exception $e) {
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->messageManager->addError(__('Exception occurred during order load'));
+                $this->_redirect('sales/order/index');
+                return;
+            }
+            $this->_title->add(sprintf("#%s", $order->getRealOrderId()));
+            $this->_view->renderLayout();
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage.php
index 2c971b878af7d07fa6b69842d40ee7e076e7cfbc..3f66e333cebd87d5eaeb125955956fec0eddc365 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage.php
@@ -30,27 +30,6 @@ namespace Magento\Sales\Controller\Adminhtml\Order\View;
  */
 class Giftmessage extends \Magento\Backend\App\Action
 {
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        try {
-            $this->_getGiftmessageSaveModel()->setGiftmessages(
-                $this->getRequest()->getParam('giftmessage')
-            )->saveAllInOrder();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('Something went wrong while saving the gift message.'));
-        }
-
-        if ($this->getRequest()->getParam('type') == 'order_item') {
-            $this->getResponse()->setBody($this->_getGiftmessageSaveModel()->getSaved() ? 'YES' : 'NO');
-        } else {
-            $this->getResponse()->setBody(__('The gift message has been saved.'));
-        }
-    }
 
     /**
      * Retrieve gift message save model
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage/Save.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..b80a315edcd7f2941a7539e2cf0d0ca6175138f8
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/View/Giftmessage/Save.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order\View\Giftmessage;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\View\Giftmessage
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_getGiftmessageSaveModel()->setGiftmessages(
+                $this->getRequest()->getParam('giftmessage')
+            )->saveAllInOrder();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('Something went wrong while saving the gift message.'));
+        }
+
+        if ($this->getRequest()->getParam('type') == 'order_item') {
+            $this->getResponse()->setBody($this->_getGiftmessageSaveModel()->getSaved() ? 'YES' : 'NO');
+        } else {
+            $this->getResponse()->setBody(__('The gift message has been saved.'));
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1bc7b12f48caa2e25f94227f4a46f5db75bbb83
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/VoidPayment.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Order;
+
+use \Magento\Backend\App\Action;
+
+class VoidPayment extends \Magento\Sales\Controller\Adminhtml\Order
+{
+    /**
+     * Attempt to void the order payment
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!($order = $this->_initOrder())) {
+            return;
+        }
+        try {
+            $order->getPayment()->void(new \Magento\Framework\Object()); // workaround for backwards compatibility
+            $order->save();
+            $this->messageManager->addSuccess(__('The payment has been voided.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We couldn\'t void the payment.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('sales/*/view', array('order_id' => $order->getId()));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..66b25fa5a15d33e92c1618a83eea2b312310ee86
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Index.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment;
+
+abstract class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Init layout, menu and breadcrumb
+     *
+     * @return $this
+     */
+    protected function _initAction()
+    {
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Sales::sales_shipment'
+        )->_addBreadcrumb(
+            __('Sales'),
+            __('Sales')
+        )->_addBreadcrumb(
+            __('Shipments'),
+            __('Shipments')
+        );
+        return $this;
+    }
+
+    /**
+     * Shipments grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Shipments'));
+
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Pdfshipments.php
similarity index 55%
rename from app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment.php
rename to app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Pdfshipments.php
index 8a25080ee2c3ca40461d7c0b89d687c6ee449d99..11b79cd31fe2ccf78a10252d9d527c3db84763d1 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/Pdfshipments.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,16 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml\Shipment;
+namespace Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment;
 
-use Magento\Framework\App\ResponseInterface;
+use \Magento\Framework\App\ResponseInterface;
 
-/**
- * Adminhtml sales orders controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class AbstractShipment extends \Magento\Backend\App\Action
+abstract class Pdfshipments extends \Magento\Backend\App\Action
 {
     /**
      * @var \Magento\Framework\App\Response\Http\FileFactory
@@ -50,56 +46,17 @@ class AbstractShipment extends \Magento\Backend\App\Action
     }
 
     /**
-     * Init layout, menu and breadcrumb
-     *
-     * @return $this
-     */
-    protected function _initAction()
-    {
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Sales::sales_shipment'
-        )->_addBreadcrumb(
-            __('Sales'),
-            __('Sales')
-        )->_addBreadcrumb(
-            __('Shipments'),
-            __('Shipments')
-        );
-        return $this;
-    }
-
-    /**
-     * Shipments grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Shipments'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Shipment information page
-     *
-     * @return void
+     * @return bool
      */
-    public function viewAction()
+    protected function _isAllowed()
     {
-        if ($shipmentId = $this->getRequest()->getParam('shipment_id')) {
-            $this->_forward('view', 'order_shipment', 'admin', array('come_from' => 'shipment'));
-        } else {
-            $this->_forward('noroute');
-        }
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
     }
 
     /**
      * @return ResponseInterface|void
      */
-    public function pdfshipmentsAction()
+    public function execute()
     {
         $shipmentIds = $this->getRequest()->getPost('shipment_ids');
         if (!empty($shipmentIds)) {
@@ -127,39 +84,4 @@ class AbstractShipment extends \Magento\Backend\App\Action
         }
         $this->_redirect('sales/*/');
     }
-
-    /**
-     * @return ResponseInterface|void
-     */
-    public function printAction()
-    {
-        $shipmentId = $this->getRequest()->getParam('shipment_id');
-        if ($shipmentId) {
-            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
-            if ($shipment) {
-                $pdf = $this->_objectManager->create(
-                    'Magento\Sales\Model\Order\Pdf\Shipment'
-                )->getPdf(
-                    array($shipment)
-                );
-                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
-                return $this->_fileFactory->create(
-                    'packingslip' . $date . '.pdf',
-                    $pdf->render(),
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            }
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * @return bool
-     */
-    protected function _isAllowed()
-    {
-        return $this->_authorization->isAllowed('Magento_Sales::shipment');
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..db8f296fcca2201fa1e3462addd7db3fe6f88477
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/PrintAction.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment;
+
+use \Magento\Framework\App\ResponseInterface;
+
+abstract class PrintAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $shipmentId = $this->getRequest()->getParam('shipment_id');
+        if ($shipmentId) {
+            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
+            if ($shipment) {
+                $pdf = $this->_objectManager->create(
+                    'Magento\Sales\Model\Order\Pdf\Shipment'
+                )->getPdf(
+                    array($shipment)
+                );
+                $date = $this->_objectManager->get('Magento\Framework\Stdlib\DateTime\DateTime')->date('Y-m-d_H-i-s');
+                return $this->_fileFactory->create(
+                    'packingslip' . $date . '.pdf',
+                    $pdf->render(),
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            }
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..d30f826a1206c6ae56c4effd8cc64d09e11981fc
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/AbstractShipment/View.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment;
+
+abstract class View extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Shipment information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($shipmentId = $this->getRequest()->getParam('shipment_id')) {
+            $this->_forward('view', 'order_shipment', 'admin', array('come_from' => 'shipment'));
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportCsv.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e4b653c54c218d0b26eced1786cdfda42e99a67
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportCsv.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCsv extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Export shipment grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $fileName = 'shipments.csv';
+        $grid = $this->_view->getLayout()->getChildBlock('sales.shipment.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            $fileName,
+            $grid->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportExcel.php
similarity index 63%
rename from app/code/Magento/Sales/Controller/Adminhtml/Shipment.php
rename to app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportExcel.php
index ae97a7c28dcd38c99b4d348743ae8e2315a173aa..e5dcb79e6b4db0c4cdf281e88280756f0ed00cfc 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Shipment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/ExportExcel.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,32 +22,35 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml;
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
 
-use Magento\Framework\App\ResponseInterface;
+use \Magento\Framework\App\ResponseInterface;
 
-/**
- * Adminhtml sales orders controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment
+class ExportExcel extends \Magento\Backend\App\Action
 {
     /**
-     * Export shipment grid to CSV format
-     *
-     * @return ResponseInterface
+     * @var \Magento\Framework\App\Response\Http\FileFactory
      */
-    public function exportCsvAction()
+    protected $_fileFactory;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
     {
-        $this->_view->loadLayout(false);
-        $fileName = 'shipments.csv';
-        $grid = $this->_view->getLayout()->getChildBlock('sales.shipment.grid', 'grid.export');
-        return $this->_fileFactory->create(
-            $fileName,
-            $grid->getCsvFile(),
-            \Magento\Framework\App\Filesystem::VAR_DIR
-        );
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
     }
 
     /**
@@ -54,7 +58,7 @@ class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShip
      *
      * @return ResponseInterface
      */
-    public function exportExcelAction()
+    public function execute()
     {
         $this->_view->loadLayout(false);
         $fileName = 'shipments.xml';
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b3f9c01ba6b64779f618d600f1cd26f5482a111c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Index
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Pdfshipments.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Pdfshipments.php
new file mode 100644
index 0000000000000000000000000000000000000000..f40ac388ac5a0d663e7bea3f032b28b7651392eb
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/Pdfshipments.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
+
+class Pdfshipments extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Pdfshipments
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/PrintAction.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1bc02f191589d7f32aecaef8e60315b2bd46799
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/PrintAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\PrintAction
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Shipment/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a9e97ce3917c3c762f6e0010e8df2be2ac07e41
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Shipment/View.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Shipment;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions.php
index 2778a5dd25e0613af350f8699a4f7e0282293f29..c284d6b03018f1ec7f6c5661806520a3a999c96c 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Transactions.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions.php
@@ -79,72 +79,6 @@ class Transactions extends \Magento\Backend\App\Action
         return $txn;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Transactions'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Sales::sales_transactions');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Ajax grid action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * View Transaction Details action
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $txn = $this->_initTransaction();
-        if (!$txn) {
-            return;
-        }
-        $this->_title->add(__('Transactions'));
-        $this->_title->add(sprintf("#%s", $txn->getTxnId()));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Sales::sales_transactions');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Fetch transaction details action
-     *
-     * @return void
-     */
-    public function fetchAction()
-    {
-        $txn = $this->_initTransaction();
-        if (!$txn) {
-            return;
-        }
-        try {
-            $txn->getOrderPaymentObject()->setOrder($txn->getOrder())->importTransactionInfo($txn);
-            $txn->save();
-            $this->messageManager->addSuccess(__('The transaction details have been updated.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t update the transaction details.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('sales/transactions/view', array('_current' => true));
-    }
-
     /**
      * Check currently called action by permissions for current user
      *
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
new file mode 100644
index 0000000000000000000000000000000000000000..a30200ed59575226a5188ecfa7270ee8aef106bd
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Fetch.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Transactions;
+
+use \Magento\Backend\App\Action;
+
+class Fetch extends \Magento\Sales\Controller\Adminhtml\Transactions
+{
+    /**
+     * Fetch transaction details action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $txn = $this->_initTransaction();
+        if (!$txn) {
+            return;
+        }
+        try {
+            $txn->getOrderPaymentObject()->setOrder($txn->getOrder())->importTransactionInfo($txn);
+            $txn->save();
+            $this->messageManager->addSuccess(__('The transaction details have been updated.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t update the transaction details.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('sales/transactions/view', array('_current' => true));
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Grid.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..10c8a4de2492e932e92adbb97a3120b158be2e4e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Grid.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Transactions;
+
+use \Magento\Backend\App\Action;
+
+class Grid extends \Magento\Sales\Controller\Adminhtml\Transactions
+{
+    /**
+     * Ajax grid action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..f63ffbe1b39efe0dce01dcff19b5bb2d18cd05ad
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Transactions;
+
+use \Magento\Backend\App\Action;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Transactions
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Transactions'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Sales::sales_transactions');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Transactions/View.php b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec6c5fcec270028283f3de9bba4986b3992a24b9
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Transactions/View.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Adminhtml\Transactions;
+
+use \Magento\Backend\App\Action;
+
+class View extends \Magento\Sales\Controller\Adminhtml\Transactions
+{
+    /**
+     * View Transaction Details action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $txn = $this->_initTransaction();
+        if (!$txn) {
+            return;
+        }
+        $this->_title->add(__('Transactions'));
+        $this->_title->add(sprintf("#%s", $txn->getTxnId()));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Sales::sales_transactions');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Download.php b/app/code/Magento/Sales/Controller/Download.php
index dd5def557b688da64dde8969d9e5af732df6f1aa..8b7e5422c3fa6c81e78ce4ad302f91eaee5a6456 100644
--- a/app/code/Magento/Sales/Controller/Download.php
+++ b/app/code/Magento/Sales/Controller/Download.php
@@ -46,54 +46,4 @@ class Download extends \Magento\Framework\App\Action\Action
         $this->_download = $download;
         parent::__construct($context);
     }
-
-    /**
-     * Custom options download action
-     *
-     * @return void
-     */
-    public function downloadCustomOptionAction()
-    {
-        $quoteItemOptionId = $this->getRequest()->getParam('id');
-        /** @var $option \Magento\Sales\Model\Quote\Item\Option */
-        $option = $this->_objectManager->create('Magento\Sales\Model\Quote\Item\Option')->load($quoteItemOptionId);
-
-        if (!$option->getId()) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        $optionId = null;
-        if (strpos($option->getCode(), AbstractProductType::OPTION_PREFIX) === 0) {
-            $optionId = str_replace(AbstractProductType::OPTION_PREFIX, '', $option->getCode());
-            if ((int)$optionId != $optionId) {
-                $optionId = null;
-            }
-        }
-        $productOption = null;
-        if ($optionId) {
-            /** @var $productOption \Magento\Catalog\Model\Product\Option */
-            $productOption = $this->_objectManager->create('Magento\Catalog\Model\Product\Option')->load($optionId);
-        }
-        if (!$productOption ||
-            !$productOption->getId() ||
-            $productOption->getProductId() != $option->getProductId() ||
-            $productOption->getType() != 'file'
-        ) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        try {
-            $info = unserialize($option->getValue());
-            if ($this->getRequest()->getParam('key') != $info['secret_key']) {
-                $this->_forward('noroute');
-                return;
-            }
-            $this->_download->downloadFile($info);
-        } catch (\Exception $e) {
-            $this->_forward('noroute');
-        }
-        exit(0);
-    }
 }
diff --git a/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
new file mode 100644
index 0000000000000000000000000000000000000000..402cc756b727b77c8725e69f5056f83acfe271ed
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Download/DownloadCustomOption.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Download;
+
+use \Magento\Catalog\Model\Product\Type\AbstractType\AbstractProductType;
+
+class DownloadCustomOption extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Custom options download action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $quoteItemOptionId = $this->getRequest()->getParam('id');
+        /** @var $option \Magento\Sales\Model\Quote\Item\Option */
+        $option = $this->_objectManager->create('Magento\Sales\Model\Quote\Item\Option')->load($quoteItemOptionId);
+
+        if (!$option->getId()) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $optionId = null;
+        if (strpos($option->getCode(), AbstractProductType::OPTION_PREFIX) === 0) {
+            $optionId = str_replace(AbstractProductType::OPTION_PREFIX, '', $option->getCode());
+            if ((int)$optionId != $optionId) {
+                $optionId = null;
+            }
+        }
+        $productOption = null;
+        if ($optionId) {
+            /** @var $productOption \Magento\Catalog\Model\Product\Option */
+            $productOption = $this->_objectManager->create('Magento\Catalog\Model\Product\Option')->load($optionId);
+        }
+        if (!$productOption ||
+            !$productOption->getId() ||
+            $productOption->getProductId() != $option->getProductId() ||
+            $productOption->getType() != 'file'
+        ) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        try {
+            $info = unserialize($option->getValue());
+            if ($this->getRequest()->getParam('key') != $info['secret_key']) {
+                $this->_forward('noroute');
+                return;
+            }
+            $this->_download->downloadFile($info);
+        } catch (\Exception $e) {
+            $this->_forward('noroute');
+        }
+        exit(0);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest.php b/app/code/Magento/Sales/Controller/Guest.php
deleted file mode 100644
index 1e3197d8598715718a2fa77889a73f7e976c074f..0000000000000000000000000000000000000000
--- a/app/code/Magento/Sales/Controller/Guest.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Sales\Controller;
-
-/**
- * Sales orders controller
- */
-class Guest extends \Magento\Sales\Controller\AbstractController
-{
-    /**
-     * Try to load valid order and register it
-     *
-     * @param int $orderId
-     * @return bool
-     */
-    protected function _loadValidOrder($orderId = null)
-    {
-        return $this->_objectManager->get(
-            'Magento\Sales\Helper\Guest'
-        )->loadValidOrder(
-            $this->_request,
-            $this->_response
-        );
-    }
-
-    /**
-     * Check order view availability
-     *
-     * @param   \Magento\Sales\Model\Order $order
-     * @return  bool
-     */
-    protected function _canViewOrder($order)
-    {
-        $currentOrder = $this->_coreRegistry->registry('current_order');
-        if ($order->getId() && $order->getId() === $currentOrder->getId()) {
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * @return void
-     */
-    protected function _viewAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-
-        $this->_view->loadLayout();
-        $this->_objectManager->get('Magento\Sales\Helper\Guest')->getBreadcrumbs();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Order view form page
-     *
-     * @return void
-     */
-    public function formAction()
-    {
-        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
-            $this->_redirect('customer/account/');
-            return;
-        }
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->getBlock('head')->setTitle(__('Orders and Returns'));
-        $this->_objectManager->get('Magento\Sales\Helper\Guest')->getBreadcrumbs();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function printInvoiceAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-
-        $invoiceId = (int)$this->getRequest()->getParam('invoice_id');
-        if ($invoiceId) {
-            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
-            $order = $invoice->getOrder();
-        } else {
-            $order = $this->_coreRegistry->registry('current_order');
-        }
-
-        if ($this->_canViewOrder($order)) {
-            if (isset($invoice)) {
-                $this->_coreRegistry->register('current_invoice', $invoice);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('sales/guest/form');
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function printShipmentAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-
-        $shipmentId = (int)$this->getRequest()->getParam('shipment_id');
-        if ($shipmentId) {
-            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
-            $order = $shipment->getOrder();
-        } else {
-            $order = $this->_coreRegistry->registry('current_order');
-        }
-        if ($this->_canViewOrder($order)) {
-            if (isset($shipment)) {
-                $this->_coreRegistry->register('current_shipment', $shipment);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('sales/guest/form');
-        }
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function printCreditmemoAction()
-    {
-        if (!$this->_loadValidOrder()) {
-            return;
-        }
-
-        $creditmemoId = (int)$this->getRequest()->getParam('creditmemo_id');
-        if ($creditmemoId) {
-            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
-            $order = $creditmemo->getOrder();
-        } else {
-            $order = $this->_coreRegistry->registry('current_order');
-        }
-
-        if ($this->_canViewOrder($order)) {
-            if (isset($creditmemo)) {
-                $this->_coreRegistry->register('current_creditmemo', $creditmemo);
-            }
-            $this->_view->loadLayout('print');
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('sales/guest/form');
-        }
-    }
-}
diff --git a/app/code/Magento/Sales/Controller/Guest/Creditmemo.php b/app/code/Magento/Sales/Controller/Guest/Creditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..d44bbe83dbfa262c67f661074f01cc2fc6f73a33
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/Creditmemo.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+class Creditmemo extends \Magento\Sales\Controller\Guest\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/Form.php b/app/code/Magento/Sales/Controller/Guest/Form.php
new file mode 100644
index 0000000000000000000000000000000000000000..5fa77e2929128c1b3e3ce0b5d37417f6d4153ac5
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/Form.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+class Form extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Order view form page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->_objectManager->get('Magento\Customer\Model\Session')->isLoggedIn()) {
+            $this->_redirect('customer/account/');
+            return;
+        }
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->getBlock('head')->setTitle(__('Orders and Returns'));
+        $this->_objectManager->get('Magento\Sales\Helper\Guest')->getBreadcrumbs();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/Invoice.php b/app/code/Magento/Sales/Controller/Guest/Invoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..5bf5c2e495590eb4a3cd28ab759ed56ef6e0d32f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/Invoice.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+class Invoice extends \Magento\Sales\Controller\Guest\View
+{
+}
diff --git a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/HashOptimized.php b/app/code/Magento/Sales/Controller/Guest/OrderLoader.php
similarity index 59%
rename from app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/HashOptimized.php
rename to app/code/Magento/Sales/Controller/Guest/OrderLoader.php
index 8935e9f995dd5649093b78e675d1be222c69efd6..90e9c35d872392d5239a4742daec32b36cd3d1b2 100644
--- a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Options/HashOptimized.php
+++ b/app/code/Magento/Sales/Controller/Guest/OrderLoader.php
@@ -1,6 +1,5 @@
 <?php
 /**
- * Hash Optimized option array
  *
  * Magento
  *
@@ -23,30 +22,33 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Tax\Model\Resource\Rule\Grid\Options;
+namespace Magento\Sales\Controller\Guest;
 
-class HashOptimized implements \Magento\Framework\Option\ArrayInterface
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\ResponseInterface;
+use Magento\Sales\Controller\AbstractController\OrderLoaderInterface;
+
+class OrderLoader implements OrderLoaderInterface
 {
     /**
-     * @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection
+     * @var \Magento\Sales\Helper\Guest
      */
-    protected $_collection;
+    protected $guestHelper;
 
     /**
-     * @param \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection
+     * @param \Magento\Sales\Helper\Guest $guestHelper
      */
-    public function __construct(\Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection)
-    {
-        $this->_collection = $collection;
+    public function __construct(
+        \Magento\Sales\Helper\Guest $guestHelper
+    ) {
+        $this->guestHelper = $guestHelper;
     }
 
     /**
-     * Return Hash Optimized array
-     *
-     * @return array
+     * {@inheritdoc}
      */
-    public function toOptionArray()
+    public function load(RequestInterface $request, ResponseInterface $response)
     {
-        return $this->_collection->toOptionHashOptimized();
+        return $this->guestHelper->loadValidOrder($request, $response);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/LoginSuccess.php b/app/code/Magento/Sales/Controller/Guest/OrderViewAuthorization.php
similarity index 58%
rename from dev/tests/functional/tests/app/Magento/User/Test/Constraint/LoginSuccess.php
rename to app/code/Magento/Sales/Controller/Guest/OrderViewAuthorization.php
index 9572885621e29fcf827bd485824e07602e793046..a9a98fdd1875205dcebc0476ff387549025c3b87 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/LoginSuccess.php
+++ b/app/code/Magento/Sales/Controller/Guest/OrderViewAuthorization.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,42 +22,34 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Sales\Controller\Guest;
 
-namespace Magento\User\Test\Constraint;
-
-use Mtf\Constraint\AbstractConstraint;
-use Magento\Backend\Test\Page\Dashboard;
+use Magento\Sales\Controller\AbstractController\OrderViewAuthorizationInterface;
 
-/**
- * Class LoginSuccess
- */
-class LoginSuccess extends AbstractConstraint
+class OrderViewAuthorization implements OrderViewAuthorizationInterface
 {
     /**
-     * Constraint severeness
-     *
-     * @var string
+     * @var \Magento\Framework\Registry
      */
-    protected $severeness = 'low';
+    protected $registry;
 
     /**
-     * Verify whether customer has logged in to the Backend
-     *
-     * @param Dashboard $dashboard
+     * @param \Magento\Framework\Registry $registry
      */
-    public function processAssert(Dashboard $dashboard)
+    public function __construct(\Magento\Framework\Registry $registry)
     {
-        \PHPUnit_Framework_Assert::assertTrue(
-            $dashboard->getAdminPanelHeader()->isLoggedIn(),
-            'Admin user was not logged in.'
-        );
+        $this->registry = $registry;
     }
 
     /**
-     * @inheritdoc
+     * {@inheritdoc}
      */
-    public function toString()
+    public function canView(\Magento\Sales\Model\Order $order)
     {
-        return 'Admin user is logged in.';
+        $currentOrder = $this->registry->registry('current_order');
+        if ($order->getId() && $order->getId() === $currentOrder->getId()) {
+            return true;
+        }
+        return false;
     }
 }
diff --git a/app/code/Magento/Sales/Controller/Guest/PrintAction.php b/app/code/Magento/Sales/Controller/Guest/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..5792725dbf88eb5994a61bf53618733f80bcfcf1
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/PrintAction.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action\Context;
+
+class PrintAction extends \Magento\Sales\Controller\AbstractController\PrintAction
+{
+    /**
+     * @param Context $context
+     * @param OrderLoader $orderLoader
+     */
+    public function __construct(Context $context, OrderLoader $orderLoader)
+    {
+        parent::__construct($context, $orderLoader);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/PrintCreditmemo.php b/app/code/Magento/Sales/Controller/Guest/PrintCreditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e7e9a9fa8b9c490278515100e459252b0e81266
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/PrintCreditmemo.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action\Context;
+
+class PrintCreditmemo extends \Magento\Sales\Controller\AbstractController\PrintCreditmemo
+{
+    /**
+     * @var OrderLoader
+     */
+    protected $orderLoader;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorization $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     * @param OrderLoader $orderLoader
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorization $orderAuthorization,
+        \Magento\Framework\Registry $registry,
+        OrderLoader $orderLoader
+    ) {
+        $this->orderLoader = $orderLoader;
+        parent::__construct($context, $orderAuthorization, $registry);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+
+        $creditmemoId = (int)$this->getRequest()->getParam('creditmemo_id');
+        if ($creditmemoId) {
+            $creditmemo = $this->_objectManager->create('Magento\Sales\Model\Order\Creditmemo')->load($creditmemoId);
+            $order = $creditmemo->getOrder();
+        } else {
+            $order = $this->_coreRegistry->registry('current_order');
+        }
+
+        if ($this->orderAuthorization->canView($order)) {
+            if (isset($creditmemo)) {
+                $this->_coreRegistry->register('current_creditmemo', $creditmemo);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('sales/guest/form');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/PrintInvoice.php b/app/code/Magento/Sales/Controller/Guest/PrintInvoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dc59776fc79d6ebad9922b2054b1c743c373213
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/PrintInvoice.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action\Context;
+
+class PrintInvoice extends \Magento\Sales\Controller\AbstractController\PrintInvoice
+{
+    /**
+     * @var OrderLoader
+     */
+    protected $orderLoader;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorization $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     * @param OrderLoader $orderLoader
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorization $orderAuthorization,
+        \Magento\Framework\Registry $registry,
+        OrderLoader $orderLoader
+    ) {
+        $this->orderLoader = $orderLoader;
+        parent::__construct($context, $orderAuthorization, $registry);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+
+        $invoiceId = (int)$this->getRequest()->getParam('invoice_id');
+        if ($invoiceId) {
+            $invoice = $this->_objectManager->create('Magento\Sales\Model\Order\Invoice')->load($invoiceId);
+            $order = $invoice->getOrder();
+        } else {
+            $order = $this->_coreRegistry->registry('current_order');
+        }
+
+        if ($this->orderAuthorization->canView($order)) {
+            if (isset($invoice)) {
+                $this->_coreRegistry->register('current_invoice', $invoice);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('sales/guest/form');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/PrintShipment.php b/app/code/Magento/Sales/Controller/Guest/PrintShipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c39e7efffe5956a608c5530098da3ac4376aa24
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/PrintShipment.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action\Context;
+
+class PrintShipment extends \Magento\Sales\Controller\AbstractController\PrintShipment
+{
+    /**
+     * @var OrderLoader
+     */
+    protected $orderLoader;
+
+    /**
+     * @param Context $context
+     * @param OrderViewAuthorization $orderAuthorization
+     * @param \Magento\Framework\Registry $registry
+     * @param OrderLoader $orderLoader
+     */
+    public function __construct(
+        Context $context,
+        OrderViewAuthorization $orderAuthorization,
+        \Magento\Framework\Registry $registry,
+        OrderLoader $orderLoader
+    ) {
+        $this->orderLoader = $orderLoader;
+        parent::__construct($context, $orderAuthorization, $registry);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+
+        $shipmentId = (int)$this->getRequest()->getParam('shipment_id');
+        if ($shipmentId) {
+            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
+            $order = $shipment->getOrder();
+        } else {
+            $order = $this->_coreRegistry->registry('current_order');
+        }
+        if ($this->orderAuthorization->canView($order)) {
+            if (isset($shipment)) {
+                $this->_coreRegistry->register('current_shipment', $shipment);
+            }
+            $this->_view->loadLayout('print');
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('sales/guest/form');
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/Reorder.php b/app/code/Magento/Sales/Controller/Guest/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..814fecf4d9a3a965ede2db087d884bdf03c3b291
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/Reorder.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action;
+
+class Reorder extends \Magento\Sales\Controller\AbstractController\Reorder
+{
+    /**
+     * @param Action\Context $context
+     * @param OrderLoader $orderLoader
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        Action\Context $context,
+        OrderLoader $orderLoader,
+        \Magento\Framework\Registry $registry
+    ) {
+        parent::__construct($context, $orderLoader, $registry);
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/Shipment.php b/app/code/Magento/Sales/Controller/Guest/Shipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..2de6911cc171dc560fab6da01be87a43ddb9738a
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/Shipment.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+class Shipment extends \Magento\Sales\Controller\Guest\View
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Guest/View.php b/app/code/Magento/Sales/Controller/Guest/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..f05dcb767818e2e1e993fc35ae9582eb1a3e458d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Guest/View.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Guest;
+
+use Magento\Framework\App\Action;
+
+class View extends \Magento\Sales\Controller\AbstractController\View
+{
+    /**
+     * @param Action\Context $context
+     * @param OrderLoader $orderLoader
+     */
+    public function __construct(Action\Context $context, OrderLoader $orderLoader)
+    {
+        parent::__construct($context, $orderLoader);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function execute()
+    {
+        if (!$this->orderLoader->load($this->_request, $this->_response)) {
+            return;
+        }
+
+        $this->_view->loadLayout();
+        $this->_objectManager->get('Magento\Sales\Helper\Guest')->getBreadcrumbs();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Order/Creditmemo.php b/app/code/Magento/Sales/Controller/Order/Creditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..30083a94e9fab558a041ebb000aaa620aa833cf7
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/Creditmemo.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class Creditmemo extends \Magento\Sales\Controller\AbstractController\Creditmemo implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order.php b/app/code/Magento/Sales/Controller/Order/History.php
similarity index 64%
rename from app/code/Magento/Sales/Controller/Order.php
rename to app/code/Magento/Sales/Controller/Order/History.php
index 5704000f16551cae5ca10d8be764417d5320d725..309886cd40fb9063ed803924c39d89a3d214e14b 100644
--- a/app/code/Magento/Sales/Controller/Order.php
+++ b/app/code/Magento/Sales/Controller/Order/History.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,37 +22,18 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller;
+namespace Magento\Sales\Controller\Order;
 
-use Magento\Framework\App\RequestInterface;
+use Magento\Sales\Controller\OrderInterface;
 
-/**
- * Sales orders controller
- */
-class Order extends \Magento\Sales\Controller\AbstractController
+class History extends \Magento\Framework\App\Action\Action implements OrderInterface
 {
-    /**
-     * Check customer authentication for some actions
-     *
-     * @param RequestInterface $request
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function dispatch(RequestInterface $request)
-    {
-        $loginUrl = $this->_objectManager->get('Magento\Customer\Helper\Data')->getLoginUrl();
-
-        if (!$this->_objectManager->get('Magento\Customer\Model\Session')->authenticate($this, $loginUrl)) {
-            $this->_actionFlag->set('', self::FLAG_NO_DISPATCH, true);
-        }
-        return parent::dispatch($request);
-    }
-
     /**
      * Customer order history
      *
      * @return void
      */
-    public function historyAction()
+    public function execute()
     {
         $this->_view->loadLayout();
         $this->_view->getLayout()->initMessages();
diff --git a/app/code/Magento/Sales/Controller/Order/Invoice.php b/app/code/Magento/Sales/Controller/Order/Invoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..ddb94011031385964614a5ebcd1d0337b6083831
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/Invoice.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class Invoice extends \Magento\Sales\Controller\AbstractController\Invoice implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/Plugin/Authentication.php b/app/code/Magento/Sales/Controller/Order/Plugin/Authentication.php
new file mode 100644
index 0000000000000000000000000000000000000000..ed578392db20be61b3b882df3e27897799c463fc
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/Plugin/Authentication.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order\Plugin;
+
+use Magento\Framework\App\RequestInterface;
+
+class Authentication
+{
+    /**
+     * @var \Magento\Customer\Helper\Data
+     */
+    protected $customerHelper;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @param \Magento\Customer\Helper\Data $customerHelper
+     * @param \Magento\Customer\Model\Session $customerSession
+     */
+    public function __construct(
+        \Magento\Customer\Helper\Data $customerHelper,
+        \Magento\Customer\Model\Session $customerSession
+    ) {
+        $this->customerHelper = $customerHelper;
+        $this->customerSession = $customerSession;
+    }
+
+    /**
+     * Authenticate user
+     *
+     * @param \Magento\Framework\App\ActionInterface $subject
+     * @param RequestInterface $request
+     * @return void
+     */
+    public function beforeDispatch(\Magento\Framework\App\ActionInterface $subject, RequestInterface $request)
+    {
+        $loginUrl = $this->customerHelper->getLoginUrl();
+
+        if (!$this->customerSession->authenticate($subject, $loginUrl)) {
+            $subject->getActionFlag()->set('', $subject::FLAG_NO_DISPATCH, true);
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Controller/Order/PrintAction.php b/app/code/Magento/Sales/Controller/Order/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1529264b877ff8c2ea855f3b6487bdde3d6822c
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/PrintAction.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class PrintAction extends \Magento\Sales\Controller\AbstractController\PrintAction implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/PrintCreditmemo.php b/app/code/Magento/Sales/Controller/Order/PrintCreditmemo.php
new file mode 100644
index 0000000000000000000000000000000000000000..d37a2c93110cdf28cd92deccf55e56d294c4533f
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/PrintCreditmemo.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class PrintCreditmemo extends \Magento\Sales\Controller\AbstractController\PrintCreditmemo implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/PrintInvoice.php b/app/code/Magento/Sales/Controller/Order/PrintInvoice.php
new file mode 100644
index 0000000000000000000000000000000000000000..00f49bcc121dbf8a281cc5789015fd0186ca185b
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/PrintInvoice.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class PrintInvoice extends \Magento\Sales\Controller\AbstractController\PrintInvoice implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/PrintShipment.php b/app/code/Magento/Sales/Controller/Order/PrintShipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..55b1d5637ce4fbd75ccba9f56696f7fcade9a4a8
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/PrintShipment.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class PrintShipment extends \Magento\Sales\Controller\AbstractController\PrintShipment implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/Reorder.php b/app/code/Magento/Sales/Controller/Order/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..4499fd431de0489f012c412b683c4ce115890c8e
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/Reorder.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class Reorder extends \Magento\Sales\Controller\AbstractController\Reorder implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/Shipment.php b/app/code/Magento/Sales/Controller/Order/Shipment.php
new file mode 100644
index 0000000000000000000000000000000000000000..021f4a9dc81617f84c15fb88100a4f61c5458b81
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/Shipment.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class Shipment extends \Magento\Sales\Controller\AbstractController\Shipment implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/Order/View.php b/app/code/Magento/Sales/Controller/Order/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..286b5742a8df05a5747eefd695e3e8f50b62e25d
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/Order/View.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller\Order;
+
+use Magento\Sales\Controller\OrderInterface;
+
+class View extends \Magento\Sales\Controller\AbstractController\View implements OrderInterface
+{
+}
diff --git a/app/code/Magento/Sales/Controller/OrderInterface.php b/app/code/Magento/Sales/Controller/OrderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f6b80745def4fb05745f1210e6f238dcd627348
--- /dev/null
+++ b/app/code/Magento/Sales/Controller/OrderInterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Controller;
+
+use Magento\Framework\App\ActionInterface;
+
+interface OrderInterface extends ActionInterface
+{
+}
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Create.php b/app/code/Magento/Sales/Model/AdminOrder/Create.php
index c8abfbb376eeee7605b14f8a46f1099fb3798a5a..85b0010452368bd9b420d933b9d5c369b9885389 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Create.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Create.php
@@ -192,6 +192,16 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
      */
     protected $stockItemService;
 
+    /**
+     * @var \Magento\Sales\Model\AdminOrder\EmailSender
+     */
+    protected $emailSender;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Item\Updater
+     */
+    protected $quoteItemUpdater;
+
     /**
      * @param \Magento\Framework\ObjectManager $objectManager
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
@@ -210,7 +220,9 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
      * @param \Magento\Customer\Helper\Data $customerHelper
      * @param CustomerGroupServiceInterface $customerGroupService
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param EmailSender $emailSender
      * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService
+     * @param \Magento\Sales\Model\Quote\Item\Updater $quoteItemUpdater
      * @param array $data
      */
     public function __construct(
@@ -231,7 +243,9 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
         \Magento\Customer\Helper\Data $customerHelper,
         CustomerGroupServiceInterface $customerGroupService,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Sales\Model\AdminOrder\EmailSender $emailSender,
         \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService,
+        \Magento\Sales\Model\Quote\Item\Updater $quoteItemUpdater,
         array $data = array()
     ) {
         $this->_objectManager = $objectManager;
@@ -251,7 +265,9 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
         $this->_customerHelper = $customerHelper;
         $this->_customerGroupService = $customerGroupService;
         $this->_scopeConfig = $scopeConfig;
+        $this->emailSender = $emailSender;
         $this->stockItemService = $stockItemService;
+        $this->quoteItemUpdater = $quoteItemUpdater;
         parent::__construct($data);
     }
 
@@ -969,60 +985,41 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
     /**
      * Update quantity of order quote items
      *
-     * @param array $data
+     * @param array $items
      * @return $this
      * @throws \Exception|\Magento\Framework\Model\Exception
      */
-    public function updateQuoteItems($data)
+    public function updateQuoteItems($items)
     {
-        if (is_array($data)) {
-            try {
-                foreach ($data as $itemId => $info) {
-                    if (!empty($info['configured'])) {
-                        $item = $this->getQuote()->updateItem($itemId, new \Magento\Framework\Object($info));
-                        $itemQty = (double)$item->getQty();
-                    } else {
-                        $item = $this->getQuote()->getItemById($itemId);
-                        $itemQty = (double)$info['qty'];
-                    }
+        if (!is_array($items)) {
+            return $this;
+        }
 
-                    if ($item) {
-                        $stockItemDo = $this->stockItemService->getStockItem($item->getProduct()->getId());
-                        if ($stockItemDo->getStockId() && !$stockItemDo->getIsQtyDecimal()) {
-                            $itemQty = (int)$itemQty;
-                        } else {
-                            $item->setIsQtyDecimal(1);
-                        }
-                        $itemQty = $itemQty > 0 ? $itemQty : 1;
-                        if (isset($info['custom_price'])) {
-                            $itemPrice = $this->_parseCustomPrice($info['custom_price']);
-                        } else {
-                            $itemPrice = null;
-                        }
-                        $noDiscount = !isset($info['use_discount']);
-
-                        if (empty($info['action']) || !empty($info['configured'])) {
-                            $item->setQty($itemQty);
-                            $item->setCustomPrice($itemPrice);
-                            $item->setOriginalCustomPrice($itemPrice);
-                            $item->setNoDiscount($noDiscount);
-                            $item->getProduct()->setIsSuperMode(true);
-                            $item->getProduct()->unsSkipCheckRequiredOption();
-                            $item->checkData();
-                        }
-                        if (!empty($info['action'])) {
-                            $this->moveQuoteItem($item, $info['action'], $itemQty);
-                        }
+        try {
+            foreach ($items as $itemId => $info) {
+                if (!empty($info['configured'])) {
+                    $item = $this->getQuote()->updateItem($itemId, $this->_objectManager->create($info));
+                    $info['qty'] = (double)$item->getQty();
+                } else {
+                    $item = $this->getQuote()->getItemById($itemId);
+                    if (!$item) {
+                        continue;
                     }
+                    $info['qty'] = (double)$info['qty'];
+                }
+                $item = $this->quoteItemUpdater->update($item, $info);
+                if ($item && !empty($info['action'])) {
+                    $this->moveQuoteItem($item, $info['action'], $item->getQty());
                 }
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->recollectCart();
-                throw $e;
-            } catch (\Exception $e) {
-                $this->_logger->logException($e);
             }
+        } catch (\Magento\Framework\Model\Exception $e) {
             $this->recollectCart();
+            throw $e;
+        } catch (\Exception $e) {
+            $this->_logger->logException($e);
         }
+        $this->recollectCart();
+
         return $this;
     }
 
@@ -1804,7 +1801,7 @@ class Create extends \Magento\Framework\Object implements \Magento\Checkout\Mode
             $order->save();
         }
         if ($this->getSendConfirmation()) {
-            $order->sendNewOrderEmail();
+            $this->emailSender->send($order);
         }
 
         $this->_eventManager->dispatch('checkout_submit_all_after', array('order' => $order, 'quote' => $quote));
diff --git a/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
new file mode 100644
index 0000000000000000000000000000000000000000..77c549d6f6ca07ca01267b35d54252bacec0742c
--- /dev/null
+++ b/app/code/Magento/Sales/Model/AdminOrder/EmailSender.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\AdminOrder;
+
+use Magento\Framework\Message\ManagerInterface;
+use Magento\Framework\Logger;
+use Magento\Sales\Model\Order;
+
+/**
+ * Class EmailSender
+ */
+class EmailSender
+{
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\Logger
+     */
+    protected $logger;
+
+    /**
+     * @param ManagerInterface $messageManager
+     * @param Logger $logger
+     */
+    public function __construct(ManagerInterface $messageManager, Logger $logger)
+    {
+        $this->messageManager = $messageManager;
+        $this->logger = $logger;
+    }
+
+    /**
+     * Send email about new order.
+     * Process mail exception
+     *
+     * @param Order $order
+     * @return bool
+     */
+    public function send(Order $order)
+    {
+        try {
+            $order->sendNewOrderEmail();
+        } catch (\Magento\Framework\Mail\Exception $exception) {
+            $this->logger->logException($exception);
+            $this->messageManager->addWarning(
+                __('You did not email your customer. Please check your email settings.')
+            );
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php b/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php
index f143e968898db8e77f2b4d3334b87449a375701a..47253a45fc1f1a89be30cbdae96de534cfd8fb44 100644
--- a/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php
+++ b/app/code/Magento/Sales/Model/AdminOrder/Product/Quote/Initializer.php
@@ -67,7 +67,7 @@ class Initializer
 
         $product->setCartQty($config->getQty());
 
-        $item = $quote->addProductAdvanced(
+        $item = $quote->addProduct(
             $product,
             $config,
             \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL
diff --git a/app/code/Magento/Sales/Model/Quote.php b/app/code/Magento/Sales/Model/Quote.php
index d30e2ff1db9e79731d0b2a6f4172fbc8ea7927a2..64c7afa775b5491944290f6b123ee131d2a5e4d3 100644
--- a/app/code/Magento/Sales/Model/Quote.php
+++ b/app/code/Magento/Sales/Model/Quote.php
@@ -304,6 +304,16 @@ class Quote extends \Magento\Framework\Model\AbstractModel
      */
     protected $stockItemService;
 
+    /**
+     * @var \Magento\Sales\Model\Quote\Item\Processor
+     */
+    protected $itemProcessor;
+
+    /**
+     * @var \Magento\Framework\Object\Factory
+     */
+    protected $objectFactory;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -327,6 +337,8 @@ class Quote extends \Magento\Framework\Model\AbstractModel
      * @param \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService
      * @param \Magento\Customer\Model\Address\Converter $addressConverter
      * @param \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService
+     * @param Quote\Item\Processor $itemProcessor
+     * @param \Magento\Framework\Object\Factory $objectFactory
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
      * @param \Magento\Framework\Data\Collection\Db $resourceCollection
      * @param array $data
@@ -354,6 +366,8 @@ class Quote extends \Magento\Framework\Model\AbstractModel
         \Magento\Customer\Service\V1\CustomerAddressServiceInterface $addressService,
         \Magento\Customer\Model\Address\Converter $addressConverter,
         \Magento\CatalogInventory\Service\V1\StockItemService $stockItemService,
+        \Magento\Sales\Model\Quote\Item\Processor $itemProcessor,
+        \Magento\Framework\Object\Factory $objectFactory,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\Db $resourceCollection = null,
         array $data = array()
@@ -378,6 +392,8 @@ class Quote extends \Magento\Framework\Model\AbstractModel
         $this->_addressService = $addressService;
         $this->_addressConverter = $addressConverter;
         $this->stockItemService = $stockItemService;
+        $this->itemProcessor = $itemProcessor;
+        $this->objectFactory = $objectFactory;
         parent::__construct($context, $registry, $resource, $resourceCollection, $data);
     }
 
@@ -1280,13 +1296,16 @@ class Quote extends \Magento\Framework\Model\AbstractModel
      * @return \Magento\Sales\Model\Quote\Item|string
      * @throws \Magento\Framework\Model\Exception
      */
-    public function addProductAdvanced(\Magento\Catalog\Model\Product $product, $request = null, $processMode = null)
-    {
+    public function addProduct(
+        \Magento\Catalog\Model\Product $product,
+        $request = null,
+        $processMode = \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL
+    ) {
         if ($request === null) {
             $request = 1;
         }
         if (is_numeric($request)) {
-            $request = new \Magento\Framework\Object(array('qty' => $request));
+            $request = $this->objectFactory->create(['qty' => $request]);
         }
         if (!$request instanceof \Magento\Framework\Object) {
             throw new \Magento\Framework\Model\Exception(
@@ -1312,14 +1331,18 @@ class Quote extends \Magento\Framework\Model\AbstractModel
 
         $parentItem = null;
         $errors = array();
+        $item = null;
         $items = array();
         foreach ($cartCandidates as $candidate) {
             // Child items can be sticked together only within their parent
             $stickWithinParent = $candidate->getParentProductId() ? $parentItem : null;
             $candidate->setStickWithinParent($stickWithinParent);
-            $item = $this->_addCatalogProduct($candidate, $candidate->getCartQty());
-            if ($request->getResetCount() && !$stickWithinParent && $item->getId() === $request->getId()) {
-                $item->setData('qty', 0);
+
+            $item = $this->getItemByProduct($candidate);
+            if (!$item) {
+                $item = $this->itemProcessor->init($candidate, $request);
+                // Add only item that is not in quote already
+                $this->addItem($item);
             }
             $items[] = $item;
 
@@ -1333,10 +1356,7 @@ class Quote extends \Magento\Framework\Model\AbstractModel
                 $item->setParentItem($parentItem);
             }
 
-            /**
-             * We specify qty after we know about parent (for stock)
-             */
-            $item->addQty($candidate->getCartQty());
+            $this->itemProcessor->prepare($item, $request, $candidate);
 
             // collect errors instead of throwing first one
             if ($item->getHasError()) {
@@ -1351,29 +1371,11 @@ class Quote extends \Magento\Framework\Model\AbstractModel
             throw new \Magento\Framework\Model\Exception(implode("\n", $errors));
         }
 
-        $this->_eventManager->dispatch('sales_quote_product_add_after', array('items' => $items));
+        $this->_eventManager->dispatch('sales_quote_product_add_after', ['items' => $items]);
 
         return $item;
     }
 
-    /**
-     * Add product to quote
-     *
-     * return error message if product type instance can't prepare product
-     *
-     * @param mixed $product
-     * @param null|float|\Magento\Framework\Object $request
-     * @return \Magento\Sales\Model\Quote\Item|string
-     */
-    public function addProduct(\Magento\Catalog\Model\Product $product, $request = null)
-    {
-        return $this->addProductAdvanced(
-            $product,
-            $request,
-            \Magento\Catalog\Model\Product\Type\AbstractType::PROCESS_MODE_FULL
-        );
-    }
-
     /**
      * Adding catalog product object data to quote
      *
diff --git a/app/code/Magento/Sales/Model/Quote/Item/Processor.php b/app/code/Magento/Sales/Model/Quote/Item/Processor.php
new file mode 100644
index 0000000000000000000000000000000000000000..f64746d0f6339ac16be23d1a688165ac63fc06ef
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Quote/Item/Processor.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Quote\Item;
+
+use \Magento\Catalog\Model\Product;
+use \Magento\Sales\Model\Quote\ItemFactory;
+use \Magento\Sales\Model\Quote\Item;
+use \Magento\Store\Model\StoreManagerInterface;
+use \Magento\Framework\App\State;
+use \Magento\Framework\Object;
+
+/**
+ * Class Processor
+ *  - initializes quote item with store_id and qty data
+ *  - updates quote item qty and custom price data
+ */
+class Processor
+{
+    /**
+     * @var \Magento\Sales\Model\Quote\ItemFactory
+     */
+    protected $quoteItemFactory;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Framework\App\State
+     */
+    protected $appState;
+
+    /**
+     * @param ItemFactory $quoteItemFactory
+     * @param StoreManagerInterface $storeManager
+     * @param State $appState
+     */
+    public function __construct(
+        ItemFactory $quoteItemFactory,
+        StoreManagerInterface $storeManager,
+        State $appState
+    ) {
+        $this->quoteItemFactory = $quoteItemFactory;
+        $this->storeManager = $storeManager;
+        $this->appState = $appState;
+    }
+
+    /**
+     * Initialize quote item object
+     *
+     * @param \Magento\Framework\Object $request
+     * @param Product $product
+     *
+     * @return \Magento\Sales\Model\Quote\Item
+     */
+    public function init(Product $product, $request)
+    {
+        $item = $this->quoteItemFactory->create();
+
+        $this->setItemStoreId($item);
+
+        /**
+         * We can't modify existing child items
+         */
+        if ($item->getId() && $product->getParentProductId()) {
+            return $item;
+        }
+
+        $item->setOptions($product->getCustomOptions());
+        $item->setProduct($product);
+
+        if ($request->getResetCount() && !$product->getStickWithinParent() && $item->getId() === $request->getId()) {
+            $item->setData('qty', 0);
+        }
+
+        return $item;
+    }
+
+    /**
+     * Set qty and custom price for quote item
+     *
+     * @param Item $item
+     * @param Object $request
+     * @param Product $candidate
+     * @return void
+     */
+    public function prepare(Item $item, Object $request, Product $candidate)
+    {
+        /**
+         * We specify qty after we know about parent (for stock)
+         */
+        $item->addQty($candidate->getCartQty());
+
+        $customPrice = $request->getCustomPrice();
+        if (!empty($customPrice)) {
+            $item->setCustomPrice($customPrice);
+            $item->setOriginalCustomPrice($customPrice);
+        }
+    }
+
+    /**
+     * Set store_id value to quote item
+     *
+     * @param Item $item
+     * @return void
+     */
+    protected function setItemStoreId(Item $item)
+    {
+        if ($this->appState->getAreaCode() === \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE) {
+            $storeId = $this->storeManager->getStore($this->storeManager->getStore()->getId())
+                ->getId();
+            $item->setStoreId($storeId);
+        } else {
+            $item->setStoreId($this->storeManager->getStore()->getId());
+        }
+    }
+}
diff --git a/app/code/Magento/Sales/Model/Quote/Item/Updater.php b/app/code/Magento/Sales/Model/Quote/Item/Updater.php
new file mode 100644
index 0000000000000000000000000000000000000000..9f5673c045cf01a253262d9e97ee673a50d90e97
--- /dev/null
+++ b/app/code/Magento/Sales/Model/Quote/Item/Updater.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Quote\Item;
+
+use \Magento\Catalog\Model\ProductFactory;
+use \Magento\Framework\Locale\FormatInterface;
+use \Magento\Sales\Model\Quote;
+use \Magento\Framework\Object\Factory as ObjectFactory;
+use \Magento\Sales\Model\Quote\Item;
+use Zend\Code\Exception\InvalidArgumentException;
+
+/**
+ * Class Updater
+ */
+class Updater
+{
+    /**
+     * @var ProductFactory
+     */
+    protected $productFactory;
+
+    /**
+     * @var FormatInterface
+     */
+    protected $localeFormat;
+
+    /**
+     * @var ObjectFactory
+     */
+    protected $objectFactory;
+
+    /**
+     * @param ProductFactory $productFactory
+     * @param FormatInterface $localeFormat
+     * @param ObjectFactory $objectFactory
+     */
+    public function __construct(
+        ProductFactory $productFactory,
+        FormatInterface $localeFormat,
+        ObjectFactory $objectFactory
+    ) {
+        $this->productFactory = $productFactory;
+        $this->localeFormat = $localeFormat;
+        $this->objectFactory = $objectFactory;
+    }
+
+    /**
+     * Update quote item qty.
+     * Custom price is updated in case 'custom_price' value exists
+     *
+     * @param Item $item
+     * @param array $info
+     * @throws InvalidArgumentException
+     * @return Updater
+     */
+    public function update(Item $item, array $info)
+    {
+        if (!isset($info['qty'])) {
+            throw new InvalidArgumentException(__('The qty value is required to update quote item.'));
+        }
+        $itemQty = $info['qty'];
+        if ($item->getProduct()->getStockItem()) {
+            if (!$item->getProduct()->getStockItem()->getIsQtyDecimal()) {
+                $itemQty = (int)$info['qty'];
+            } else {
+                $item->setIsQtyDecimal(1);
+            }
+        }
+        $itemQty = $itemQty > 0 ? $itemQty : 1;
+        if (isset($info['custom_price'])) {
+            $this->setCustomPrice($info, $item);
+        } elseif ($item->hasData('custom_price')) {
+            $this->unsetCustomPrice($item);
+        }
+
+        if (empty($info['action']) || !empty($info['configured'])) {
+            $noDiscount = !isset($info['use_discount']);
+            $item->setQty($itemQty);
+            $item->setNoDiscount($noDiscount);
+            $item->getProduct()->setIsSuperMode(true);
+            $item->getProduct()->unsSkipCheckRequiredOption();
+            $item->checkData();
+        }
+
+        return $this;
+    }
+
+    /**
+     * Prepares custom price and sets into a BuyRequest object as option of quote item
+     *
+     * @param array $info
+     * @param Item $item
+     * @return array
+     */
+    protected function setCustomPrice(array $info, Item $item)
+    {
+        $itemPrice = $this->parseCustomPrice($info['custom_price']);
+        /** @var \Magento\Framework\Object $infoBuyRequest */
+        $infoBuyRequest = $item->getBuyRequest();
+        if ($infoBuyRequest) {
+            $infoBuyRequest->setCustomPrice($itemPrice);
+
+            $infoBuyRequest->setValue(serialize($infoBuyRequest->getData()));
+            $infoBuyRequest->setCode('info_buyRequest');
+            $infoBuyRequest->setProduct($item->getProduct());
+
+            $item->addOption($infoBuyRequest);
+        }
+
+        $item->setCustomPrice($itemPrice);
+        $item->setOriginalCustomPrice($itemPrice);
+    }
+
+    /**
+     * Unset custom_price data for quote item
+     *
+     * @param Item $item
+     * @return void
+     */
+    protected function unsetCustomPrice(Item $item)
+    {
+        /** @var \Magento\Framework\Object $infoBuyRequest */
+        $infoBuyRequest = $item->getBuyRequest();
+        if ($infoBuyRequest->hasData('custom_price')) {
+            $infoBuyRequest->unsetData('custom_price');
+
+            $infoBuyRequest->setValue(serialize($infoBuyRequest->getData()));
+            $infoBuyRequest->setCode('info_buyRequest');
+            $infoBuyRequest->setProduct($item->getProduct());
+            $item->addOption($infoBuyRequest);
+        }
+
+        $item->unsetData('custom_price');
+        $item->unsetData('original_custom_price');
+    }
+
+    /**
+     * Return formatted price
+     *
+     * @param float|int $price
+     * @return float|int
+     */
+    protected function parseCustomPrice($price)
+    {
+        $price = $this->localeFormat->getNumber($price);
+        return $price > 0 ? $price : 0;
+    }
+}
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
index e002ac9b155e8ee7f7ec4694cc4dee5acc444ccc..3dbae800e8d082f86d0febcc6436cb86da03980f 100644
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -79,4 +79,7 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Sales\Controller\OrderInterface">
+        <plugin name="authentication" type="\Magento\Sales\Controller\Order\Plugin\Authentication"/>
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/etc/frontend/di.xml b/app/code/Magento/Sales/etc/frontend/di.xml
index e417a782684cea5d932b1951c4e7eca6013d895a..d04738d9797626e8ee1887d8ac40573589a5625e 100644
--- a/app/code/Magento/Sales/etc/frontend/di.xml
+++ b/app/code/Magento/Sales/etc/frontend/di.xml
@@ -24,6 +24,8 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Sales\Controller\AbstractController\OrderLoaderInterface" type="\Magento\Sales\Controller\AbstractController\OrderLoader" />
+    <preference for="Magento\Sales\Controller\AbstractController\OrderViewAuthorizationInterface" type="\Magento\Sales\Controller\AbstractController\OrderViewAuthorization" />
     <type name="Magento\Core\Model\Url\SecurityInfo">
         <arguments>
             <argument name="secureUrlList" xsi:type="array">
diff --git a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit.php b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit.php
index 8d9597f0cab6149d2a4f841360c6d05c2f607b46..8e96ba0d463684a70f5b37b5844f40f62509076b 100644
--- a/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit.php
+++ b/app/code/Magento/SalesRule/Block/Adminhtml/Promo/Quote/Edit.php
@@ -36,12 +36,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -64,7 +64,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_addButton(
+        $this->buttonList->add(
             'save_and_continue_edit',
             array(
                 'class' => 'save',
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php
index 71e3c20fb3746744c8df1bb9cf67a10d2afc9cce..b60b01dc311a0525d83da58c8849eeb67b632c16 100644
--- a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote.php
@@ -96,430 +96,6 @@ class Quote extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Cart Price Rules'));
-
-        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * New promo quote action
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Promo quote edit action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
-
-        if ($id) {
-            $model->load($id);
-            if (!$model->getRuleId()) {
-                $this->messageManager->addError(__('This rule no longer exists.'));
-                $this->_redirect('sales_rule/*');
-                return;
-            }
-        }
-
-        $this->_title->add($model->getRuleId() ? $model->getName() : __('New Cart Price Rule'));
-
-        // set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
-        if (!empty($data)) {
-            $model->addData($data);
-        }
-
-        $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
-        $model->getActions()->setJsFormObject('rule_actions_fieldset');
-
-        $this->_coreRegistry->register('current_promo_quote_rule', $model);
-
-        $this->_initAction();
-        $this->_view->getLayout()->getBlock('promo_quote_edit')->setData('action', $this->getUrl('sales_rule/*/save'));
-
-        $this->_addBreadcrumb($id ? __('Edit Rule') : __('New Rule'), $id ? __('Edit Rule') : __('New Rule'));
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Promo quote save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        if ($this->getRequest()->getPost()) {
-            try {
-                /** @var $model \Magento\SalesRule\Model\Rule */
-                $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
-                $this->_eventManager->dispatch(
-                    'adminhtml_controller_salesrule_prepare_save',
-                    array('request' => $this->getRequest())
-                );
-                $data = $this->getRequest()->getPost();
-                $inputFilter = new \Zend_Filter_Input(
-                    array('from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter),
-                    array(),
-                    $data
-                );
-                $data = $inputFilter->getUnescaped();
-                $id = $this->getRequest()->getParam('rule_id');
-                if ($id) {
-                    $model->load($id);
-                    if ($id != $model->getId()) {
-                        throw new \Magento\Framework\Model\Exception(__('The wrong rule is specified.'));
-                    }
-                }
-
-                $session = $this->_objectManager->get('Magento\Backend\Model\Session');
-
-                $validateResult = $model->validateData(new \Magento\Framework\Object($data));
-                if ($validateResult !== true) {
-                    foreach ($validateResult as $errorMessage) {
-                        $this->messageManager->addError($errorMessage);
-                    }
-                    $session->setPageData($data);
-                    $this->_redirect('sales_rule/*/edit', array('id' => $model->getId()));
-                    return;
-                }
-
-                if (isset(
-                    $data['simple_action']
-                ) && $data['simple_action'] == 'by_percent' && isset(
-                    $data['discount_amount']
-                )
-                ) {
-                    $data['discount_amount'] = min(100, $data['discount_amount']);
-                }
-                if (isset($data['rule']['conditions'])) {
-                    $data['conditions'] = $data['rule']['conditions'];
-                }
-                if (isset($data['rule']['actions'])) {
-                    $data['actions'] = $data['rule']['actions'];
-                }
-                unset($data['rule']);
-                $model->loadPost($data);
-
-                $useAutoGeneration = (int)(!empty($data['use_auto_generation']));
-                $model->setUseAutoGeneration($useAutoGeneration);
-
-                $session->setPageData($model->getData());
-
-                $model->save();
-                $this->messageManager->addSuccess(__('The rule has been saved.'));
-                $session->setPageData(false);
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('sales_rule/*/edit', array('id' => $model->getId()));
-                    return;
-                }
-                $this->_redirect('sales_rule/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $id = (int)$this->getRequest()->getParam('rule_id');
-                if (!empty($id)) {
-                    $this->_redirect('sales_rule/*/edit', array('id' => $id));
-                } else {
-                    $this->_redirect('sales_rule/*/new');
-                }
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('An error occurred while saving the rule data. Please review the log and try again.')
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
-                $this->_redirect('sales_rule/*/edit', array('id' => $this->getRequest()->getParam('rule_id')));
-                return;
-            }
-        }
-        $this->_redirect('sales_rule/*/');
-    }
-
-    /**
-     * Delete promo quote action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        if ($id) {
-            try {
-                $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
-                $model->load($id);
-                $model->delete();
-                $this->messageManager->addSuccess(__('The rule has been deleted.'));
-                $this->_redirect('sales_rule/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(
-                    __('An error occurred while deleting the rule. Please review the log and try again.')
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                $this->_redirect('sales_rule/*/edit', array('id' => $this->getRequest()->getParam('id')));
-                return;
-            }
-        }
-        $this->messageManager->addError(__('We can\'t find a rule to delete.'));
-        $this->_redirect('sales_rule/*/');
-    }
-
-    /**
-     * New condition html action
-     *
-     * @return void
-     */
-    public function newConditionHtmlAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
-        $type = $typeArr[0];
-
-        $model = $this->_objectManager->create(
-            $type
-        )->setId(
-            $id
-        )->setType(
-            $type
-        )->setRule(
-            $this->_objectManager->create('Magento\SalesRule\Model\Rule')
-        )->setPrefix(
-            'conditions'
-        );
-        if (!empty($typeArr[1])) {
-            $model->setAttribute($typeArr[1]);
-        }
-
-        if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
-            $model->setJsFormObject($this->getRequest()->getParam('form'));
-            $html = $model->asHtmlRecursive();
-        } else {
-            $html = '';
-        }
-        $this->getResponse()->setBody($html);
-    }
-
-    /**
-     * New action html action
-     *
-     * @return void
-     */
-    public function newActionHtmlAction()
-    {
-        $id = $this->getRequest()->getParam('id');
-        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
-        $type = $typeArr[0];
-
-        $model = $this->_objectManager->create(
-            $type
-        )->setId(
-            $id
-        )->setType(
-            $type
-        )->setRule(
-            $this->_objectManager->create('Magento\SalesRule\Model\Rule')
-        )->setPrefix(
-            'actions'
-        );
-        if (!empty($typeArr[1])) {
-            $model->setAttribute($typeArr[1]);
-        }
-
-        if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
-            $model->setJsFormObject($this->getRequest()->getParam('form'));
-            $html = $model->asHtmlRecursive();
-        } else {
-            $html = '';
-        }
-        $this->getResponse()->setBody($html);
-    }
-
-    /**
-     * Apply rules action
-     *
-     * @return void
-     */
-    public function applyRulesAction()
-    {
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Coupon codes grid
-     *
-     * @return void
-     */
-    public function couponsGridAction()
-    {
-        $this->_initRule();
-        $this->_view->loadLayout()->renderLayout();
-    }
-
-    /**
-     * Export coupon codes as excel xml file
-     *
-     * @return \Magento\Framework\App\ResponseInterface|null
-     */
-    public function exportCouponsXmlAction()
-    {
-        $this->_initRule();
-        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
-        if ($rule->getId()) {
-            $fileName = 'coupon_codes.xml';
-            $content = $this->_view->getLayout()->createBlock(
-                'Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab\Coupons\Grid'
-            )->getExcelFile(
-                $fileName
-            );
-            return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-        } else {
-            $this->_redirect('sales_rule/*/detail', array('_current' => true));
-            return;
-        }
-    }
-
-    /**
-     * Export coupon codes as CSV file
-     *
-     * @return \Magento\Framework\App\ResponseInterface|null
-     */
-    public function exportCouponsCsvAction()
-    {
-        $this->_initRule();
-        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
-        if ($rule->getId()) {
-            $fileName = 'coupon_codes.csv';
-            $content = $this->_view->getLayout()->createBlock(
-                'Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab\Coupons\Grid'
-            )->getCsvFile();
-            return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-        } else {
-            $this->_redirect('sales_rule/*/detail', array('_current' => true));
-            return;
-        }
-    }
-
-    /**
-     * Coupons mass delete action
-     *
-     * @return void
-     */
-    public function couponsMassDeleteAction()
-    {
-        $this->_initRule();
-        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
-
-        if (!$rule->getId()) {
-            $this->_forward('noroute');
-        }
-
-        $codesIds = $this->getRequest()->getParam('ids');
-
-        if (is_array($codesIds)) {
-
-            $couponsCollection = $this->_objectManager->create(
-                'Magento\SalesRule\Model\Resource\Coupon\Collection'
-            )->addFieldToFilter(
-                'coupon_id',
-                array('in' => $codesIds)
-            );
-
-            foreach ($couponsCollection as $coupon) {
-                $coupon->delete();
-            }
-        }
-    }
-
-    /**
-     * Generate Coupons action
-     *
-     * @return void
-     */
-    public function generateAction()
-    {
-        if (!$this->getRequest()->isAjax()) {
-            $this->_forward('noroute');
-            return;
-        }
-        $result = array();
-        $this->_initRule();
-
-        /** @var $rule \Magento\SalesRule\Model\Rule */
-        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
-
-        if (!$rule->getId()) {
-            $result['error'] = __('Rule is not defined');
-        } else {
-            try {
-                $data = $this->getRequest()->getParams();
-                if (!empty($data['to_date'])) {
-                    $inputFilter = new \Zend_Filter_Input(array('to_date' => $this->_dateFilter), array(), $data);
-                    $data = $inputFilter->getUnescaped();
-                }
-
-                /** @var $generator \Magento\SalesRule\Model\Coupon\Massgenerator */
-                $generator = $this->_objectManager->get('Magento\SalesRule\Model\Coupon\Massgenerator');
-                if (!$generator->validateData($data)) {
-                    $result['error'] = __('Invalid data provided');
-                } else {
-                    $generator->setData($data);
-                    $generator->generatePool();
-                    $generated = $generator->getGeneratedCount();
-                    $this->messageManager->addSuccess(__('%1 coupon(s) have been generated.', $generated));
-                    $this->_view->getLayout()->initMessages();
-                    $result['messages'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml();
-                }
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $result['error'] = $e->getMessage();
-            } catch (\Exception $e) {
-                $result['error'] = __(
-                    'Something went wrong while generating coupons. Please review the log and try again.'
-                );
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            }
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Chooser source action
-     *
-     * @return void
-     */
-    public function chooserAction()
-    {
-        $uniqId = $this->getRequest()->getParam('uniq_id');
-        $chooserBlock = $this->_view->getLayout()->createBlock(
-            'Magento\SalesRule\Block\Adminhtml\Promo\Widget\Chooser',
-            '',
-            array('data' => array('id' => $uniqId))
-        );
-        $this->getResponse()->setBody($chooserBlock->toHtml());
-    }
-
     /**
      * Returns result of current user permission check on resource and privilege
      *
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ApplyRules.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ApplyRules.php
new file mode 100644
index 0000000000000000000000000000000000000000..61f48f2a171550f0fd584dd91a04090d910ff919
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ApplyRules.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class ApplyRules extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Apply rules action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Chooser.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Chooser.php
new file mode 100644
index 0000000000000000000000000000000000000000..5809e21750a7fc489af5336cc47b7c501d150ed4
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Chooser.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Chooser extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Chooser source action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $uniqId = $this->getRequest()->getParam('uniq_id');
+        $chooserBlock = $this->_view->getLayout()->createBlock(
+            'Magento\SalesRule\Block\Adminhtml\Promo\Widget\Chooser',
+            '',
+            array('data' => array('id' => $uniqId))
+        );
+        $this->getResponse()->setBody($chooserBlock->toHtml());
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsGrid.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b388729d86db2e2367b0b2198792f6d56e0d47c
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsGrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class CouponsGrid extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Coupon codes grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initRule();
+        $this->_view->loadLayout()->renderLayout();
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsMassDelete.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsMassDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..a08610289c844f0bd4db0cf4eeb9e7aa8c43bcd1
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/CouponsMassDelete.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class CouponsMassDelete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Coupons mass delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_initRule();
+        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
+
+        if (!$rule->getId()) {
+            $this->_forward('noroute');
+        }
+
+        $codesIds = $this->getRequest()->getParam('ids');
+
+        if (is_array($codesIds)) {
+
+            $couponsCollection = $this->_objectManager->create(
+                'Magento\SalesRule\Model\Resource\Coupon\Collection'
+            )->addFieldToFilter(
+                'coupon_id',
+                array('in' => $codesIds)
+            );
+
+            foreach ($couponsCollection as $coupon) {
+                $coupon->delete();
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac47575f507a558625d7de494023d64aeaf26df2
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Delete.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Delete extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Delete promo quote action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        if ($id) {
+            try {
+                $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
+                $model->load($id);
+                $model->delete();
+                $this->messageManager->addSuccess(__('The rule has been deleted.'));
+                $this->_redirect('sales_rule/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('An error occurred while deleting the rule. Please review the log and try again.')
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_redirect('sales_rule/*/edit', array('id' => $this->getRequest()->getParam('id')));
+                return;
+            }
+        }
+        $this->messageManager->addError(__('We can\'t find a rule to delete.'));
+        $this->_redirect('sales_rule/*/');
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b31e11b792160808e618eabae5e7261eb278eeb
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Edit.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Edit extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Promo quote edit action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
+
+        if ($id) {
+            $model->load($id);
+            if (!$model->getRuleId()) {
+                $this->messageManager->addError(__('This rule no longer exists.'));
+                $this->_redirect('sales_rule/*');
+                return;
+            }
+        }
+
+        $this->_title->add($model->getRuleId() ? $model->getName() : __('New Cart Price Rule'));
+
+        // set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getPageData(true);
+        if (!empty($data)) {
+            $model->addData($data);
+        }
+
+        $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
+        $model->getActions()->setJsFormObject('rule_actions_fieldset');
+
+        $this->_coreRegistry->register('current_promo_quote_rule', $model);
+
+        $this->_initAction();
+        $this->_view->getLayout()->getBlock('promo_quote_edit')->setData('action', $this->getUrl('sales_rule/*/save'));
+
+        $this->_addBreadcrumb($id ? __('Edit Rule') : __('New Rule'), $id ? __('Edit Rule') : __('New Rule'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..cccd4fe1a1b871e27a58e155272e3e5e60ed2fdb
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsCsv.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class ExportCouponsCsv extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Export coupon codes as CSV file
+     *
+     * @return \Magento\Framework\App\ResponseInterface|null
+     */
+    public function execute()
+    {
+        $this->_initRule();
+        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
+        if ($rule->getId()) {
+            $fileName = 'coupon_codes.csv';
+            $content = $this->_view->getLayout()->createBlock(
+                'Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab\Coupons\Grid'
+            )->getCsvFile();
+            return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+        } else {
+            $this->_redirect('sales_rule/*/detail', array('_current' => true));
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php
new file mode 100644
index 0000000000000000000000000000000000000000..3229084369bdb6ce32101ebcb6c8b89055a638cc
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/ExportCouponsXml.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class ExportCouponsXml extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Export coupon codes as excel xml file
+     *
+     * @return \Magento\Framework\App\ResponseInterface|null
+     */
+    public function execute()
+    {
+        $this->_initRule();
+        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
+        if ($rule->getId()) {
+            $fileName = 'coupon_codes.xml';
+            $content = $this->_view->getLayout()->createBlock(
+                'Magento\SalesRule\Block\Adminhtml\Promo\Quote\Edit\Tab\Coupons\Grid'
+            )->getExcelFile(
+                $fileName
+            );
+            return $this->_fileFactory->create($fileName, $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+        } else {
+            $this->_redirect('sales_rule/*/detail', array('_current' => true));
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab0c53cae17065925778195fd37bb8381130d276
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Generate.php
@@ -0,0 +1,81 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Generate extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Generate Coupons action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->getRequest()->isAjax()) {
+            $this->_forward('noroute');
+            return;
+        }
+        $result = array();
+        $this->_initRule();
+
+        /** @var $rule \Magento\SalesRule\Model\Rule */
+        $rule = $this->_coreRegistry->registry('current_promo_quote_rule');
+
+        if (!$rule->getId()) {
+            $result['error'] = __('Rule is not defined');
+        } else {
+            try {
+                $data = $this->getRequest()->getParams();
+                if (!empty($data['to_date'])) {
+                    $inputFilter = new \Zend_Filter_Input(array('to_date' => $this->_dateFilter), array(), $data);
+                    $data = $inputFilter->getUnescaped();
+                }
+
+                /** @var $generator \Magento\SalesRule\Model\Coupon\Massgenerator */
+                $generator = $this->_objectManager->get('Magento\SalesRule\Model\Coupon\Massgenerator');
+                if (!$generator->validateData($data)) {
+                    $result['error'] = __('Invalid data provided');
+                } else {
+                    $generator->setData($data);
+                    $generator->generatePool();
+                    $generated = $generator->getGeneratedCount();
+                    $this->messageManager->addSuccess(__('%1 coupon(s) have been generated.', $generated));
+                    $this->_view->getLayout()->initMessages();
+                    $result['messages'] = $this->_view->getLayout()->getMessagesBlock()->getGroupedHtml();
+                }
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $result['error'] = $e->getMessage();
+            } catch (\Exception $e) {
+                $result['error'] = __(
+                    'Something went wrong while generating coupons. Please review the log and try again.'
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            }
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e75115dc883c29939f8cf7a624342707a50344f
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Index extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Cart Price Rules'));
+
+        $this->_initAction()->_addBreadcrumb(__('Catalog'), __('Catalog'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d7878eb2ae39fe0e2eaf7aee22e88df5dfc2789
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class NewAction extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * New promo quote action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7d62c449bd1fe9e7221e48edf8d4140427da0af
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewActionHtml.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class NewActionHtml extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * New action html action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
+        $type = $typeArr[0];
+
+        $model = $this->_objectManager->create(
+            $type
+        )->setId(
+            $id
+        )->setType(
+            $type
+        )->setRule(
+            $this->_objectManager->create('Magento\SalesRule\Model\Rule')
+        )->setPrefix(
+            'actions'
+        );
+        if (!empty($typeArr[1])) {
+            $model->setAttribute($typeArr[1]);
+        }
+
+        if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
+            $model->setJsFormObject($this->getRequest()->getParam('form'));
+            $html = $model->asHtmlRecursive();
+        } else {
+            $html = '';
+        }
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewConditionHtml.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewConditionHtml.php
new file mode 100644
index 0000000000000000000000000000000000000000..d5adb0410b0aa3484d58096906976fac5ccfdf10
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/NewConditionHtml.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class NewConditionHtml extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * New condition html action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $id = $this->getRequest()->getParam('id');
+        $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
+        $type = $typeArr[0];
+
+        $model = $this->_objectManager->create(
+            $type
+        )->setId(
+            $id
+        )->setType(
+            $type
+        )->setRule(
+            $this->_objectManager->create('Magento\SalesRule\Model\Rule')
+        )->setPrefix(
+            'conditions'
+        );
+        if (!empty($typeArr[1])) {
+            $model->setAttribute($typeArr[1]);
+        }
+
+        if ($model instanceof \Magento\Rule\Model\Condition\AbstractCondition) {
+            $model->setJsFormObject($this->getRequest()->getParam('form'));
+            $html = $model->asHtmlRecursive();
+        } else {
+            $html = '';
+        }
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c8389f5a42db335e11f5e63ce7baff65e8be973
--- /dev/null
+++ b/app/code/Magento/SalesRule/Controller/Adminhtml/Promo/Quote/Save.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\SalesRule\Controller\Adminhtml\Promo\Quote;
+
+class Save extends \Magento\SalesRule\Controller\Adminhtml\Promo\Quote
+{
+    /**
+     * Promo quote save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->getPost()) {
+            try {
+                /** @var $model \Magento\SalesRule\Model\Rule */
+                $model = $this->_objectManager->create('Magento\SalesRule\Model\Rule');
+                $this->_eventManager->dispatch(
+                    'adminhtml_controller_salesrule_prepare_save',
+                    array('request' => $this->getRequest())
+                );
+                $data = $this->getRequest()->getPost();
+                $inputFilter = new \Zend_Filter_Input(
+                    array('from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter),
+                    array(),
+                    $data
+                );
+                $data = $inputFilter->getUnescaped();
+                $id = $this->getRequest()->getParam('rule_id');
+                if ($id) {
+                    $model->load($id);
+                    if ($id != $model->getId()) {
+                        throw new \Magento\Framework\Model\Exception(__('The wrong rule is specified.'));
+                    }
+                }
+
+                $session = $this->_objectManager->get('Magento\Backend\Model\Session');
+
+                $validateResult = $model->validateData(new \Magento\Framework\Object($data));
+                if ($validateResult !== true) {
+                    foreach ($validateResult as $errorMessage) {
+                        $this->messageManager->addError($errorMessage);
+                    }
+                    $session->setPageData($data);
+                    $this->_redirect('sales_rule/*/edit', array('id' => $model->getId()));
+                    return;
+                }
+
+                if (isset(
+                    $data['simple_action']
+                ) && $data['simple_action'] == 'by_percent' && isset(
+                    $data['discount_amount']
+                )
+                ) {
+                    $data['discount_amount'] = min(100, $data['discount_amount']);
+                }
+                if (isset($data['rule']['conditions'])) {
+                    $data['conditions'] = $data['rule']['conditions'];
+                }
+                if (isset($data['rule']['actions'])) {
+                    $data['actions'] = $data['rule']['actions'];
+                }
+                unset($data['rule']);
+                $model->loadPost($data);
+
+                $useAutoGeneration = (int)(!empty($data['use_auto_generation']));
+                $model->setUseAutoGeneration($useAutoGeneration);
+
+                $session->setPageData($model->getData());
+
+                $model->save();
+                $this->messageManager->addSuccess(__('The rule has been saved.'));
+                $session->setPageData(false);
+                if ($this->getRequest()->getParam('back')) {
+                    $this->_redirect('sales_rule/*/edit', array('id' => $model->getId()));
+                    return;
+                }
+                $this->_redirect('sales_rule/*/');
+                return;
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $id = (int)$this->getRequest()->getParam('rule_id');
+                if (!empty($id)) {
+                    $this->_redirect('sales_rule/*/edit', array('id' => $id));
+                } else {
+                    $this->_redirect('sales_rule/*/new');
+                }
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError(
+                    __('An error occurred while saving the rule data. Please review the log and try again.')
+                );
+                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setPageData($data);
+                $this->_redirect('sales_rule/*/edit', array('id' => $this->getRequest()->getParam('rule_id')));
+                return;
+            }
+        }
+        $this->_redirect('sales_rule/*/');
+    }
+}
diff --git a/app/code/Magento/Sendfriend/Controller/Product.php b/app/code/Magento/Sendfriend/Controller/Product.php
index 2aa8d88dcca39a2b6b95599fd05067f272bdfc3c..5d0018629e6c1ebd935d569371e15fdeefda6c16 100644
--- a/app/code/Magento/Sendfriend/Controller/Product.php
+++ b/app/code/Magento/Sendfriend/Controller/Product.php
@@ -146,106 +146,4 @@ class Product extends \Magento\Framework\App\Action\Action
 
         return $model;
     }
-
-    /**
-     * Show Send to a Friend Form
-     *
-     * @return void
-     */
-    public function sendAction()
-    {
-        $product = $this->_initProduct();
-        $model = $this->_initSendToFriendModel();
-
-        if (!$product) {
-            $this->_forward('noroute');
-            return;
-        }
-        /* @var $session \Magento\Catalog\Model\Session */
-        $catalogSession = $this->_objectManager->get('Magento\Catalog\Model\Session');
-
-        if ($model->getMaxSendsToFriend() && $model->isExceedLimit()) {
-            $this->messageManager->addNotice(
-                __('You can\'t send messages more than %1 times an hour.', $model->getMaxSendsToFriend())
-            );
-        }
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-
-        $this->_eventManager->dispatch('sendfriend_product', array('product' => $product));
-        $data = $catalogSession->getSendfriendFormData();
-        if ($data) {
-            $catalogSession->setSendfriendFormData(true);
-            $block = $this->_view->getLayout()->getBlock('sendfriend.send');
-            if ($block) {
-                $block->setFormData($data);
-            }
-        }
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Send Email Post Action
-     *
-     * @return void
-     */
-    public function sendmailAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('*/*/send', array('_current' => true));
-        }
-
-        $product = $this->_initProduct();
-        $model = $this->_initSendToFriendModel();
-        $data = $this->getRequest()->getPost();
-
-        if (!$product || !$data) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        $categoryId = $this->getRequest()->getParam('cat_id', null);
-        if ($categoryId) {
-            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
-            $product->setCategory($category);
-            $this->_coreRegistry->register('current_category', $category);
-        }
-
-        $model->setSender($this->getRequest()->getPost('sender'));
-        $model->setRecipients($this->getRequest()->getPost('recipients'));
-        $model->setProduct($product);
-
-        /* @var $session \Magento\Catalog\Model\Session */
-        $catalogSession = $this->_objectManager->get('Magento\Catalog\Model\Session');
-        try {
-            $validate = $model->validate();
-            if ($validate === true) {
-                $model->send();
-                $this->messageManager->addSuccess(__('The link to a friend was sent.'));
-                $url = $product->getProductUrl();
-                $this->getResponse()->setRedirect($this->_redirect->success($url));
-                return;
-            } else {
-                if (is_array($validate)) {
-                    foreach ($validate as $errorMessage) {
-                        $this->messageManager->addError($errorMessage);
-                    }
-                } else {
-                    $this->messageManager->addError(__('We found some problems with the data.'));
-                }
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Some emails were not sent.'));
-        }
-
-        // save form data
-        $catalogSession->setSendfriendFormData($data);
-
-        $url = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*/send', array('_current' => true));
-        $this->getResponse()->setRedirect($this->_redirect->error($url));
-    }
 }
diff --git a/app/code/Magento/Sendfriend/Controller/Product/Send.php b/app/code/Magento/Sendfriend/Controller/Product/Send.php
new file mode 100644
index 0000000000000000000000000000000000000000..939e984917590bdaf43f30514da2ed8591dc498c
--- /dev/null
+++ b/app/code/Magento/Sendfriend/Controller/Product/Send.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sendfriend\Controller\Product;
+
+class Send extends \Magento\Sendfriend\Controller\Product
+{
+    /**
+     * Show Send to a Friend Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $product = $this->_initProduct();
+        $model = $this->_initSendToFriendModel();
+
+        if (!$product) {
+            $this->_forward('noroute');
+            return;
+        }
+        /* @var $session \Magento\Catalog\Model\Session */
+        $catalogSession = $this->_objectManager->get('Magento\Catalog\Model\Session');
+
+        if ($model->getMaxSendsToFriend() && $model->isExceedLimit()) {
+            $this->messageManager->addNotice(
+                __('You can\'t send messages more than %1 times an hour.', $model->getMaxSendsToFriend())
+            );
+        }
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+
+        $this->_eventManager->dispatch('sendfriend_product', array('product' => $product));
+        $data = $catalogSession->getSendfriendFormData();
+        if ($data) {
+            $catalogSession->setSendfriendFormData(true);
+            $block = $this->_view->getLayout()->getBlock('sendfriend.send');
+            if ($block) {
+                $block->setFormData($data);
+            }
+        }
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sendfriend/Controller/Product/Sendmail.php b/app/code/Magento/Sendfriend/Controller/Product/Sendmail.php
new file mode 100644
index 0000000000000000000000000000000000000000..04267ccb4d6ff3e0bf7663f2921c322b6868a183
--- /dev/null
+++ b/app/code/Magento/Sendfriend/Controller/Product/Sendmail.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sendfriend\Controller\Product;
+
+class Sendmail extends \Magento\Sendfriend\Controller\Product
+{
+    /**
+     * Send Email Post Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            return $this->_redirect('*/*/send', array('_current' => true));
+        }
+
+        $product = $this->_initProduct();
+        $model = $this->_initSendToFriendModel();
+        $data = $this->getRequest()->getPost();
+
+        if (!$product || !$data) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $categoryId = $this->getRequest()->getParam('cat_id', null);
+        if ($categoryId) {
+            $category = $this->_objectManager->create('Magento\Catalog\Model\Category')->load($categoryId);
+            $product->setCategory($category);
+            $this->_coreRegistry->register('current_category', $category);
+        }
+
+        $model->setSender($this->getRequest()->getPost('sender'));
+        $model->setRecipients($this->getRequest()->getPost('recipients'));
+        $model->setProduct($product);
+
+        /* @var $session \Magento\Catalog\Model\Session */
+        $catalogSession = $this->_objectManager->get('Magento\Catalog\Model\Session');
+        try {
+            $validate = $model->validate();
+            if ($validate === true) {
+                $model->send();
+                $this->messageManager->addSuccess(__('The link to a friend was sent.'));
+                $url = $product->getProductUrl();
+                $this->getResponse()->setRedirect($this->_redirect->success($url));
+                return;
+            } else {
+                if (is_array($validate)) {
+                    foreach ($validate as $errorMessage) {
+                        $this->messageManager->addError($errorMessage);
+                    }
+                } else {
+                    $this->messageManager->addError(__('We found some problems with the data.'));
+                }
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Some emails were not sent.'));
+        }
+
+        // save form data
+        $catalogSession->setSendfriendFormData($data);
+
+        $url = $this->_objectManager->create('Magento\Framework\UrlInterface')->getUrl('*/*/send', array('_current' => true));
+        $this->getResponse()->setRedirect($this->_redirect->error($url));
+    }
+}
diff --git a/app/code/Magento/Shipping/Block/Adminhtml/Create.php b/app/code/Magento/Shipping/Block/Adminhtml/Create.php
index b90c52125ae4e76fe619618a44a5946308d2b671..977cdeb32b9f24b41c8406c5f77dbadd9daf51d8 100644
--- a/app/code/Magento/Shipping/Block/Adminhtml/Create.php
+++ b/app/code/Magento/Shipping/Block/Adminhtml/Create.php
@@ -36,12 +36,12 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -59,8 +59,8 @@ class Create extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('save');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('save');
+        $this->buttonList->remove('delete');
     }
 
     /**
diff --git a/app/code/Magento/Shipping/Block/Adminhtml/View.php b/app/code/Magento/Shipping/Block/Adminhtml/View.php
index 0ae2857bac64a3324761dec2319b5166ac10705b..bc8f91c118042b6997eac9fdbb4de31a4d87ae21 100644
--- a/app/code/Magento/Shipping/Block/Adminhtml/View.php
+++ b/app/code/Magento/Shipping/Block/Adminhtml/View.php
@@ -38,12 +38,12 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -61,15 +61,15 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_removeButton('reset');
-        $this->_removeButton('delete');
+        $this->buttonList->remove('reset');
+        $this->buttonList->remove('delete');
         if (!$this->getShipment()) {
             return;
         }
 
         if ($this->_authorization->isAllowed('Magento_Sales::emails')) {
-            $this->_updateButton('save', 'label', __('Send Tracking Information'));
-            $this->_updateButton(
+            $this->buttonList->update('save', 'label', __('Send Tracking Information'));
+            $this->buttonList->update(
                 'save',
                 'onclick',
                 "deleteConfirm('" . __(
@@ -79,7 +79,7 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
         }
 
         if ($this->getShipment()->getId()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'print',
                 array(
                     'label' => __('Print'),
@@ -156,13 +156,13 @@ class View extends \Magento\Backend\Block\Widget\Form\Container
     {
         if ($flag) {
             if ($this->getShipment()->getBackUrl()) {
-                return $this->_updateButton(
+                return $this->buttonList->update(
                     'back',
                     'onclick',
                     'setLocation(\'' . $this->getShipment()->getBackUrl() . '\')'
                 );
             }
-            return $this->_updateButton(
+            return $this->buttonList->update(
                 'back',
                 'onclick',
                 'setLocation(\'' . $this->getUrl('sales/shipment/') . '\')'
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php
deleted file mode 100644
index 8a2967cbb17e4a1fbdcb58a8ec6059abf6d2dfaf..0000000000000000000000000000000000000000
--- a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment.php
+++ /dev/null
@@ -1,777 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Shipping\Controller\Adminhtml\Order;
-
-use Magento\Framework\App\ResponseInterface;
-
-/**
- * Adminhtml order shipment controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-class Shipment extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry;
-
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileFactory;
-
-    /**
-     * @var \Magento\Shipping\Model\CarrierFactory
-     */
-    protected $_carrierFactory;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-     * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Shipping\Model\CarrierFactory $carrierFactory
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
-        \Magento\Framework\Registry $coreRegistry,
-        \Magento\Shipping\Model\CarrierFactory $carrierFactory
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        $this->_fileFactory = $fileFactory;
-        $this->_carrierFactory = $carrierFactory;
-        parent::__construct($context, $fileFactory);
-    }
-
-    /**
-     * Initialize shipment items QTY
-     *
-     * @return array
-     */
-    protected function _getItemQtys()
-    {
-        $data = $this->getRequest()->getParam('shipment');
-        if (isset($data['items'])) {
-            $qtys = $data['items'];
-        } else {
-            $qtys = array();
-        }
-        return $qtys;
-    }
-
-    /**
-     * Initialize shipment model instance
-     *
-     * @throws \Magento\Framework\Model\Exception
-     * @return \Magento\Sales\Model\Order\Shipment|bool
-     */
-    protected function _initShipment()
-    {
-        $this->_title->add(__('Shipments'));
-
-        $shipment = false;
-        $shipmentId = $this->getRequest()->getParam('shipment_id');
-        $orderId = $this->getRequest()->getParam('order_id');
-        if ($shipmentId) {
-            $shipment = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment')->load($shipmentId);
-        } elseif ($orderId) {
-            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->load($orderId);
-
-            /**
-             * Check order existing
-             */
-            if (!$order->getId()) {
-                $this->messageManager->addError(__('The order no longer exists.'));
-                return false;
-            }
-            /**
-             * Check shipment is available to create separate from invoice
-             */
-            if ($order->getForcedShipmentWithInvoice()) {
-                $this->messageManager->addError(__('Cannot do shipment for the order separately from invoice.'));
-                return false;
-            }
-            /**
-             * Check shipment create availability
-             */
-            if (!$order->canShip()) {
-                $this->messageManager->addError(__('Cannot do shipment for the order.'));
-                return false;
-            }
-            $savedQtys = $this->_getItemQtys();
-            $shipment = $this->_objectManager->create(
-                'Magento\Sales\Model\Service\Order',
-                array('order' => $order)
-            )->prepareShipment(
-                $savedQtys
-            );
-
-            $tracks = $this->getRequest()->getPost('tracking');
-            if ($tracks) {
-                foreach ($tracks as $data) {
-                    if (empty($data['number'])) {
-                        throw new \Magento\Framework\Model\Exception(__('Please enter a tracking number.'));
-                    }
-                    $track = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment\Track')->addData($data);
-                    $shipment->addTrack($track);
-                }
-            }
-        }
-
-        $this->_coreRegistry->register('current_shipment', $shipment);
-        return $shipment;
-    }
-
-    /**
-     * Save shipment and order in one transaction
-     *
-     * @param \Magento\Sales\Model\Order\Shipment $shipment
-     * @return $this
-     */
-    protected function _saveShipment($shipment)
-    {
-        $shipment->getOrder()->setIsInProcess(true);
-        $transactionSave = $this->_objectManager->create(
-            'Magento\Framework\DB\Transaction'
-        )->addObject(
-            $shipment
-        )->addObject(
-            $shipment->getOrder()
-        )->save();
-
-        return $this;
-    }
-
-    /**
-     * Shipment information page
-     *
-     * @return void
-     */
-    public function viewAction()
-    {
-        $shipment = $this->_initShipment();
-        if ($shipment) {
-            $this->_title->add("#" . $shipment->getIncrementId());
-            $this->_view->loadLayout();
-            $this->_view->getLayout()->getBlock(
-                'sales_shipment_view'
-            )->updateBackButtonUrl(
-                $this->getRequest()->getParam('come_from')
-            );
-            $this->_setActiveMenu('Magento_Sales::sales_order');
-            $this->_view->renderLayout();
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Start create shipment action
-     *
-     * @return void
-     */
-    public function startAction()
-    {
-        /**
-         * Clear old values for shipment qty's
-         */
-        $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
-    }
-
-    /**
-     * Shipment create page
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $shipment = $this->_initShipment();
-        if ($shipment) {
-            $this->_title->add(__('New Shipment'));
-
-            $comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
-            if ($comment) {
-                $shipment->setCommentText($comment);
-            }
-
-            $this->_view->loadLayout();
-            $this->_setActiveMenu('Magento_Sales::sales_order');
-            $this->_view->renderLayout();
-        } else {
-            $this->_redirect('*/order/view', array('order_id' => $this->getRequest()->getParam('order_id')));
-        }
-    }
-
-    /**
-     * Save shipment
-     * We can save only new shipment. Existing shipments are not editable
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $data = $this->getRequest()->getPost('shipment');
-        if (!empty($data['comment_text'])) {
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setCommentText($data['comment_text']);
-        }
-
-        try {
-            $shipment = $this->_initShipment();
-            if (!$shipment) {
-                $this->_forward('noroute');
-                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->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
-            $responseAjax = new \Magento\Framework\Object();
-            $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
-
-            if ($isNeedCreateLabel && $this->_createShippingLabel($shipment)) {
-                $responseAjax->setOk(true);
-            }
-
-            $this->_saveShipment($shipment);
-
-            $shipment->sendEmail(!empty($data['send_email']), $comment);
-
-            $shipmentCreatedMessage = __('The shipment has been created.');
-            $labelCreatedMessage = __('You created the shipping label.');
-
-            $this->messageManager->addSuccess(
-                $isNeedCreateLabel ? $shipmentCreatedMessage . ' ' . $labelCreatedMessage : $shipmentCreatedMessage
-            );
-            $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            if ($isNeedCreateLabel) {
-                $responseAjax->setError(true);
-                $responseAjax->setMessage($e->getMessage());
-            } else {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
-            }
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            if ($isNeedCreateLabel) {
-                $responseAjax->setError(true);
-                $responseAjax->setMessage(__('An error occurred while creating shipping label.'));
-            } else {
-                $this->messageManager->addError(__('Cannot save shipment.'));
-                $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
-            }
-        }
-        if ($isNeedCreateLabel) {
-            $this->getResponse()->representJson($responseAjax->toJson());
-        } else {
-            $this->_redirect('sales/order/view', array('order_id' => $shipment->getOrderId()));
-        }
-    }
-
-    /**
-     * Send email with shipment data to customer
-     *
-     * @return void
-     */
-    public function emailAction()
-    {
-        try {
-            $shipment = $this->_initShipment();
-            if ($shipment) {
-                $shipment->sendEmail(true)->setEmailSent(true)->save();
-                $historyItem = $this->_objectManager->create(
-                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
-                )->getUnnotifiedForInstance(
-                    $shipment,
-                    \Magento\Sales\Model\Order\Shipment::HISTORY_ENTITY_NAME
-                );
-                if ($historyItem) {
-                    $historyItem->setIsCustomerNotified(1);
-                    $historyItem->save();
-                }
-                $this->messageManager->addSuccess(__('You sent the shipment.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('Cannot send shipment information.'));
-        }
-        $this->_redirect('*/*/view', array('shipment_id' => $this->getRequest()->getParam('shipment_id')));
-    }
-
-    /**
-     * Add new tracking number action
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function addTrackAction()
-    {
-        try {
-            $carrier = $this->getRequest()->getPost('carrier');
-            $number = $this->getRequest()->getPost('number');
-            $title = $this->getRequest()->getPost('title');
-            if (empty($carrier)) {
-                throw new \Magento\Framework\Model\Exception(__('Please specify a carrier.'));
-            }
-            if (empty($number)) {
-                throw new \Magento\Framework\Model\Exception(__('Please enter a tracking number.'));
-            }
-            $shipment = $this->_initShipment();
-            if ($shipment) {
-                $track = $this->_objectManager->create(
-                    'Magento\Sales\Model\Order\Shipment\Track'
-                )->setNumber(
-                    $number
-                )->setCarrierCode(
-                    $carrier
-                )->setTitle(
-                    $title
-                );
-                $shipment->addTrack($track)->save();
-
-                $this->_view->loadLayout();
-                $response = $this->_view->getLayout()->getBlock('shipment_tracking')->toHtml();
-            } else {
-                $response = array(
-                    'error' => true,
-                    'message' => __('Cannot initialize shipment for adding tracking number.')
-                );
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot add tracking number.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Remove tracking number from shipment
-     *
-     * @return void
-     */
-    public function removeTrackAction()
-    {
-        $trackId = $this->getRequest()->getParam('track_id');
-        $track = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment\Track')->load($trackId);
-        if ($track->getId()) {
-            try {
-                if ($this->_initShipment()) {
-                    $track->delete();
-
-                    $this->_view->loadLayout();
-                    $response = $this->_view->getLayout()->getBlock('shipment_tracking')->toHtml();
-                } else {
-                    $response = array(
-                        'error' => true,
-                        'message' => __('Cannot initialize shipment for delete tracking number.')
-                    );
-                }
-            } catch (\Exception $e) {
-                $response = array('error' => true, 'message' => __('Cannot delete tracking number.'));
-            }
-        } else {
-            $response = array('error' => true, 'message' => __('Cannot load track with retrieving identifier.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Add comment to shipment history
-     *
-     * @return void
-     */
-    public function addCommentAction()
-    {
-        try {
-            $this->getRequest()->setParam('shipment_id', $this->getRequest()->getParam('id'));
-            $data = $this->getRequest()->getPost('comment');
-            if (empty($data['comment'])) {
-                throw new \Magento\Framework\Model\Exception(__("The comment text field cannot be empty."));
-            }
-            $shipment = $this->_initShipment();
-            $shipment->addComment(
-                $data['comment'],
-                isset($data['is_customer_notified']),
-                isset($data['is_visible_on_front'])
-            );
-            $shipment->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
-            $shipment->save();
-
-            $this->_view->loadLayout(false);
-            $response = $this->_view->getLayout()->getBlock('shipment_comments')->toHtml();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
-        }
-        if (is_array($response)) {
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response)
-            );
-        } else {
-            $this->getResponse()->setBody($response);
-        }
-    }
-
-    /**
-     * Create shipping label for specific shipment with validation.
-     *
-     * @param \Magento\Sales\Model\Order\Shipment $shipment
-     * @throws \Magento\Framework\Model\Exception
-     * @return bool
-     */
-    protected function _createShippingLabel(\Magento\Sales\Model\Order\Shipment $shipment)
-    {
-        if (!$shipment) {
-            return false;
-        }
-        $order = $shipment->getOrder();
-        $carrier = $this->_carrierFactory->create($order->getShippingMethod(true)->getCarrierCode());
-        if (!$carrier->isShippingLabelsAvailable()) {
-            return false;
-        }
-        $shipment->setPackages($this->getRequest()->getParam('packages'));
-        $response = $this->_objectManager->create(
-            'Magento\Shipping\Model\Shipping\Labels'
-        )->requestToShipment(
-            $shipment
-        );
-        if ($response->hasErrors()) {
-            throw new \Magento\Framework\Model\Exception($response->getErrors());
-        }
-        if (!$response->hasInfo()) {
-            return false;
-        }
-        $labelsContent = array();
-        $trackingNumbers = array();
-        $info = $response->getInfo();
-        foreach ($info as $inf) {
-            if (!empty($inf['tracking_number']) && !empty($inf['label_content'])) {
-                $labelsContent[] = $inf['label_content'];
-                $trackingNumbers[] = $inf['tracking_number'];
-            }
-        }
-        $outputPdf = $this->_combineLabelsPdf($labelsContent);
-        $shipment->setShippingLabel($outputPdf->render());
-        $carrierCode = $carrier->getCarrierCode();
-        $carrierTitle = $this->_objectManager->get(
-            'Magento\Framework\App\Config\ScopeConfigInterface',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-        )->getValue(
-            'carriers/' . $carrierCode . '/title',
-            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
-            $shipment->getStoreId()
-        );
-        if ($trackingNumbers) {
-            foreach ($trackingNumbers as $trackingNumber) {
-                $track = $this->_objectManager->create(
-                    'Magento\Sales\Model\Order\Shipment\Track'
-                )->setNumber(
-                    $trackingNumber
-                )->setCarrierCode(
-                    $carrierCode
-                )->setTitle(
-                    $carrierTitle
-                );
-                $shipment->addTrack($track);
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Create shipping label action for specific shipment
-     *
-     * @return void
-     */
-    public function createLabelAction()
-    {
-        $response = new \Magento\Framework\Object();
-        try {
-            $shipment = $this->_initShipment();
-            if ($this->_createShippingLabel($shipment)) {
-                $shipment->save();
-                $this->messageManager->addSuccess(__('You created the shipping label.'));
-                $response->setOk(true);
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $response->setError(true);
-            $response->setMessage($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $response->setError(true);
-            $response->setMessage(__('An error occurred while creating shipping label.'));
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * Print label for one specific shipment
-     *
-     * @return ResponseInterface|void
-     */
-    public function printLabelAction()
-    {
-        try {
-            $shipment = $this->_initShipment();
-            $labelContent = $shipment->getShippingLabel();
-            if ($labelContent) {
-                $pdfContent = null;
-                if (stripos($labelContent, '%PDF-') !== false) {
-                    $pdfContent = $labelContent;
-                } else {
-                    $pdf = new \Zend_Pdf();
-                    $page = $this->_createPdfPageFromImageString($labelContent);
-                    if (!$page) {
-                        $this->messageManager->addError(
-                            __(
-                                'We don\'t recognize or support the file extension in this shipment: %1.',
-                                $shipment->getIncrementId()
-                            )
-                        );
-                    }
-                    $pdf->pages[] = $page;
-                    $pdfContent = $pdf->render();
-                }
-
-                return $this->_fileFactory->create(
-                    'ShippingLabel(' . $shipment->getIncrementId() . ').pdf',
-                    $pdfContent,
-                    \Magento\Framework\App\Filesystem::VAR_DIR,
-                    'application/pdf'
-                );
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->messageManager->addError(__('An error occurred while creating shipping label.'));
-        }
-        $this->_redirect(
-            'adminhtml/order_shipment/view',
-            array('shipment_id' => $this->getRequest()->getParam('shipment_id'))
-        );
-    }
-
-    /**
-     * Create pdf document with information about packages
-     *
-     * @return ResponseInterface|void
-     */
-    public function printPackageAction()
-    {
-        $shipment = $this->_initShipment();
-
-        if ($shipment) {
-            $pdf = $this->_objectManager->create('Magento\Shipping\Model\Order\Pdf\Packaging')->getPdf($shipment);
-            return $this->_fileFactory->create(
-                'packingslip' . $this->_objectManager->get(
-                    'Magento\Framework\Stdlib\DateTime\DateTime'
-                )->date(
-                    'Y-m-d_H-i-s'
-                ) . '.pdf',
-                $pdf->render(),
-                \Magento\Framework\App\Filesystem::VAR_DIR,
-                'application/pdf'
-            );
-        } else {
-            $this->_forward('noroute');
-        }
-    }
-
-    /**
-     * Batch print shipping labels for whole shipments.
-     * Push pdf document with shipping labels to user browser
-     *
-     * @return ResponseInterface|void
-     */
-    public function massPrintShippingLabelAction()
-    {
-        $request = $this->getRequest();
-        $ids = $request->getParam('order_ids');
-        $createdFromOrders = !empty($ids);
-        $shipments = null;
-        $labelsContent = array();
-        switch ($request->getParam('massaction_prepare_key')) {
-            case 'shipment_ids':
-                $ids = $request->getParam('shipment_ids');
-                array_filter($ids, 'intval');
-                if (!empty($ids)) {
-                    $shipments = $this->_objectManager->create(
-                        'Magento\Sales\Model\Resource\Order\Shipment\Collection'
-                    )->addFieldToFilter(
-                        'entity_id',
-                        array('in' => $ids)
-                    );
-                }
-                break;
-            case 'order_ids':
-                $ids = $request->getParam('order_ids');
-                array_filter($ids, 'intval');
-                if (!empty($ids)) {
-                    $shipments = $this->_objectManager->create(
-                        'Magento\Sales\Model\Resource\Order\Shipment\Collection'
-                    )->setOrderFilter(
-                        array('in' => $ids)
-                    );
-                }
-                break;
-        }
-
-        if ($shipments && $shipments->getSize()) {
-            foreach ($shipments as $shipment) {
-                $labelContent = $shipment->getShippingLabel();
-                if ($labelContent) {
-                    $labelsContent[] = $labelContent;
-                }
-            }
-        }
-
-        if (!empty($labelsContent)) {
-            $outputPdf = $this->_combineLabelsPdf($labelsContent);
-            return $this->_fileFactory->create(
-                'ShippingLabels.pdf',
-                $outputPdf->render(),
-                \Magento\Framework\App\Filesystem::VAR_DIR,
-                'application/pdf'
-            );
-        }
-
-        if ($createdFromOrders) {
-            $this->messageManager->addError(__('There are no shipping labels related to selected orders.'));
-            $this->_redirect('sales/order/index');
-        } else {
-            $this->messageManager->addError(__('There are no shipping labels related to selected shipments.'));
-            $this->_redirect('sales/shipment/index');
-        }
-    }
-
-    /**
-     * Combine array of labels as instance PDF
-     *
-     * @param array $labelsContent
-     * @return \Zend_Pdf
-     */
-    protected function _combineLabelsPdf(array $labelsContent)
-    {
-        $outputPdf = new \Zend_Pdf();
-        foreach ($labelsContent as $content) {
-            if (stripos($content, '%PDF-') !== false) {
-                $pdfLabel = \Zend_Pdf::parse($content);
-                foreach ($pdfLabel->pages as $page) {
-                    $outputPdf->pages[] = clone $page;
-                }
-            } else {
-                $page = $this->_createPdfPageFromImageString($content);
-                if ($page) {
-                    $outputPdf->pages[] = $page;
-                }
-            }
-        }
-        return $outputPdf;
-    }
-
-    /**
-     * Create \Zend_Pdf_Page instance with image from $imageString. Supports JPEG, PNG, GIF, WBMP, and GD2 formats.
-     *
-     * @param string $imageString
-     * @return \Zend_Pdf_Page|false
-     */
-    protected function _createPdfPageFromImageString($imageString)
-    {
-        /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
-        $directory = $this->_objectManager->get(
-            'Magento\Framework\App\Filesystem'
-        )->getDirectoryWrite(
-            \Magento\Framework\App\Filesystem::TMP_DIR
-        );
-        $directory->create();
-        $image = imagecreatefromstring($imageString);
-        if (!$image) {
-            return false;
-        }
-
-        $xSize = imagesx($image);
-        $ySize = imagesy($image);
-        $page = new \Zend_Pdf_Page($xSize, $ySize);
-
-        imageinterlace($image, 0);
-        $tmpFileName = $directory->getAbsolutePath('shipping_labels_' . uniqid(\Magento\Framework\Math\Random::getRandomNumber()) . time() . '.png');
-        imagepng($image, $tmpFileName);
-        $pdfImage = \Zend_Pdf_Image::imageWithPath($tmpFileName);
-        $page->drawImage($pdfImage, 0, 0, $xSize, $ySize);
-        $directory->delete($directory->getRelativePath($tmpFileName));
-        return $page;
-    }
-
-    /**
-     * Return grid with shipping items for Ajax request
-     *
-     * @return ResponseInterface
-     */
-    public function getShippingItemsGridAction()
-    {
-        $this->_initShipment();
-        return $this->getResponse()->setBody(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Shipping\Block\Adminhtml\Order\Packaging\Grid'
-            )->setIndex(
-                $this->getRequest()->getParam('index')
-            )->toHtml()
-        );
-    }
-}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php
new file mode 100644
index 0000000000000000000000000000000000000000..d69935e42ce1f3f3dbb8a14ffe0cfa4a696a56ec
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddComment.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use Magento\Backend\App\Action;
+
+class AddComment extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Add comment to shipment history
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getRequest()->setParam('shipment_id', $this->getRequest()->getParam('id'));
+            $data = $this->getRequest()->getPost('comment');
+            if (empty($data['comment'])) {
+                throw new \Magento\Framework\Model\Exception(__("The comment text field cannot be empty."));
+            }
+            $this->_title->add(__('Shipments'));
+            $shipment = $this->shipmentLoader->load($this->_request);
+            $shipment->addComment(
+                $data['comment'],
+                isset($data['is_customer_notified']),
+                isset($data['is_visible_on_front'])
+            );
+            $shipment->sendUpdateEmail(!empty($data['is_customer_notified']), $data['comment']);
+            $shipment->save();
+
+            $this->_view->loadLayout(false);
+            $response = $this->_view->getLayout()->getBlock('shipment_comments')->toHtml();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot add new comment.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddTrack.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddTrack.php
new file mode 100644
index 0000000000000000000000000000000000000000..deef6bb787871c27ff48743c4e6e710792b01e70
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/AddTrack.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class AddTrack extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Add new tracking number action
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function execute()
+    {
+        try {
+            $carrier = $this->getRequest()->getPost('carrier');
+            $number = $this->getRequest()->getPost('number');
+            $title = $this->getRequest()->getPost('title');
+            if (empty($carrier)) {
+                throw new \Magento\Framework\Model\Exception(__('Please specify a carrier.'));
+            }
+            if (empty($number)) {
+                throw new \Magento\Framework\Model\Exception(__('Please enter a tracking number.'));
+            }
+            $this->_title->add(__('Shipments'));
+            $shipment = $this->shipmentLoader->load($this->_request);
+            if ($shipment) {
+                $track = $this->_objectManager->create(
+                    'Magento\Sales\Model\Order\Shipment\Track'
+                )->setNumber(
+                    $number
+                )->setCarrierCode(
+                    $carrier
+                )->setTitle(
+                    $title
+                );
+                $shipment->addTrack($track)->save();
+
+                $this->_view->loadLayout();
+                $response = $this->_view->getLayout()->getBlock('shipment_tracking')->toHtml();
+            } else {
+                $response = array(
+                    'error' => true,
+                    'message' => __('Cannot initialize shipment for adding tracking number.')
+                );
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $response = array('error' => true, 'message' => __('Cannot add tracking number.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
new file mode 100644
index 0000000000000000000000000000000000000000..11903806c8aae49f13d527cb1c60da32a8a284a4
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/CreateLabel.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class CreateLabel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @var \Magento\Shipping\Model\Shipping\LabelGenerator
+     */
+    protected $labelGenerator;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
+        \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        $this->labelGenerator = $labelGenerator;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Create shipping label action for specific shipment
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        try {
+            $shipment = $this->shipmentLoader->load($this->_request);
+            if ($this->labelGenerator->create($shipment, $this->_request)) {
+                $shipment->save();
+                $this->messageManager->addSuccess(__('You created the shipping label.'));
+                $response->setOk(true);
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $response->setError(true);
+            $response->setMessage($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $response->setError(true);
+            $response->setMessage(__('An error occurred while creating shipping label.'));
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php
new file mode 100644
index 0000000000000000000000000000000000000000..13365a26921527d4620112fe3673bc2ea73e2adb
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Email.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class Email extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Send email with shipment data to customer
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $shipment = $this->shipmentLoader->load($this->_request);
+            if ($shipment) {
+                $shipment->sendEmail(true)->setEmailSent(true)->save();
+                $historyItem = $this->_objectManager->create(
+                    'Magento\Sales\Model\Resource\Order\Status\History\Collection'
+                )->getUnnotifiedForInstance(
+                    $shipment,
+                    \Magento\Sales\Model\Order\Shipment::HISTORY_ENTITY_NAME
+                );
+                if ($historyItem) {
+                    $historyItem->setIsCustomerNotified(1);
+                    $historyItem->save();
+                }
+                $this->messageManager->addSuccess(__('You sent the shipment.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('Cannot send shipment information.'));
+        }
+        $this->_redirect('*/*/view', array('shipment_id' => $this->getRequest()->getParam('shipment_id')));
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/GetShippingItemsGrid.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/GetShippingItemsGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd4a7838abd04d99c4ec787976e79dc46077d352
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/GetShippingItemsGrid.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class GetShippingItemsGrid extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Return grid with shipping items for Ajax request
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->shipmentLoader->load($this->_request);
+        return $this->getResponse()->setBody(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Shipping\Block\Adminhtml\Order\Packaging\Grid'
+            )->setIndex(
+                $this->getRequest()->getParam('index')
+            )->toHtml()
+        );
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Index.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce10b88938f2fae52fea0c97e00f16eb22d548f8
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Index.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Index
+{
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/MassPrintShippingLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/MassPrintShippingLabel.php
new file mode 100644
index 0000000000000000000000000000000000000000..764bce4d25d2630fc0fdb522f09dfde9c926163c
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/MassPrintShippingLabel.php
@@ -0,0 +1,131 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class MassPrintShippingLabel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Model\Shipping\LabelGenerator
+     */
+    protected $labelGenerator;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->labelGenerator = $labelGenerator;
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Batch print shipping labels for whole shipments.
+     * Push pdf document with shipping labels to user browser
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $request = $this->getRequest();
+        $ids = $request->getParam('order_ids');
+        $createdFromOrders = !empty($ids);
+        $shipments = null;
+        $labelsContent = array();
+        switch ($request->getParam('massaction_prepare_key')) {
+            case 'shipment_ids':
+                $ids = $request->getParam('shipment_ids');
+                array_filter($ids, 'intval');
+                if (!empty($ids)) {
+                    $shipments = $this->_objectManager->create(
+                        'Magento\Sales\Model\Resource\Order\Shipment\Collection'
+                    )->addFieldToFilter(
+                        'entity_id',
+                        array('in' => $ids)
+                    );
+                }
+                break;
+            case 'order_ids':
+                $ids = $request->getParam('order_ids');
+                array_filter($ids, 'intval');
+                if (!empty($ids)) {
+                    $shipments = $this->_objectManager->create(
+                        'Magento\Sales\Model\Resource\Order\Shipment\Collection'
+                    )->setOrderFilter(
+                        array('in' => $ids)
+                    );
+                }
+                break;
+        }
+
+        if ($shipments && $shipments->getSize()) {
+            foreach ($shipments as $shipment) {
+                $labelContent = $shipment->getShippingLabel();
+                if ($labelContent) {
+                    $labelsContent[] = $labelContent;
+                }
+            }
+        }
+
+        if (!empty($labelsContent)) {
+            $outputPdf = $this->labelGenerator->combineLabelsPdf($labelsContent);
+            return $this->_fileFactory->create(
+                'ShippingLabels.pdf',
+                $outputPdf->render(),
+                \Magento\Framework\App\Filesystem::VAR_DIR,
+                'application/pdf'
+            );
+        }
+
+        if ($createdFromOrders) {
+            $this->messageManager->addError(__('There are no shipping labels related to selected orders.'));
+            $this->_redirect('sales/order/index');
+        } else {
+            $this->messageManager->addError(__('There are no shipping labels related to selected shipments.'));
+            $this->_redirect('sales/shipment/index');
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..03698fe75c8fb93ab9b15fc558a8aad1ee398e7a
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/NewAction.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class NewAction extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Shipment create page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Shipments'));
+        $shipment = $this->shipmentLoader->load($this->_request);
+        if ($shipment) {
+            $this->_title->add(__('New Shipment'));
+
+            $comment = $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
+            if ($comment) {
+                $shipment->setCommentText($comment);
+            }
+
+            $this->_view->loadLayout();
+            $this->_setActiveMenu('Magento_Sales::sales_order');
+            $this->_view->renderLayout();
+        } else {
+            $this->_redirect('*/order/view', array('order_id' => $this->getRequest()->getParam('order_id')));
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Pdfshipments.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Pdfshipments.php
new file mode 100644
index 0000000000000000000000000000000000000000..c18a564732552acb1a1f3266bdc07421e0a7f83d
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Pdfshipments.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+class Pdfshipments extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\Pdfshipments
+{
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintAction.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..13c0ea4e31d849d590847c86ca51194496e9e764
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintAction.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+class PrintAction extends \Magento\Sales\Controller\Adminhtml\Shipment\AbstractShipment\PrintAction
+{
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
new file mode 100644
index 0000000000000000000000000000000000000000..898bcb4346525b8b56d140c74fef20170148bcc1
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintLabel.php
@@ -0,0 +1,120 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class PrintLabel extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @var \Magento\Shipping\Model\Shipping\LabelGenerator
+     */
+    protected $labelGenerator;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
+        \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        $this->labelGenerator = $labelGenerator;
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Print label for one specific shipment
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        try {
+            $shipment = $this->shipmentLoader->load($this->_request);
+            $labelContent = $shipment->getShippingLabel();
+            if ($labelContent) {
+                $pdfContent = null;
+                if (stripos($labelContent, '%PDF-') !== false) {
+                    $pdfContent = $labelContent;
+                } else {
+                    $pdf = new \Zend_Pdf();
+                    $page = $this->labelGenerator->createPdfPageFromImageString($labelContent);
+                    if (!$page) {
+                        $this->messageManager->addError(
+                            __(
+                                'We don\'t recognize or support the file extension in this shipment: %1.',
+                                $shipment->getIncrementId()
+                            )
+                        );
+                    }
+                    $pdf->pages[] = $page;
+                    $pdfContent = $pdf->render();
+                }
+
+                return $this->_fileFactory->create(
+                    'ShippingLabel(' . $shipment->getIncrementId() . ').pdf',
+                    $pdfContent,
+                    \Magento\Framework\App\Filesystem::VAR_DIR,
+                    'application/pdf'
+                );
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->messageManager->addError(__('An error occurred while creating shipping label.'));
+        }
+        $this->_redirect(
+            'adminhtml/order_shipment/view',
+            array('shipment_id' => $this->getRequest()->getParam('shipment_id'))
+        );
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintPackage.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintPackage.php
new file mode 100644
index 0000000000000000000000000000000000000000..6a34fe5d3c87126897684c566b78e92cc6eab751
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/PrintPackage.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Framework\App\ResponseInterface;
+use \Magento\Backend\App\Action;
+
+class PrintPackage extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileFactory;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        $this->_fileFactory = $fileFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Create pdf document with information about packages
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $shipment = $this->shipmentLoader->load($this->_request);
+
+        if ($shipment) {
+            $pdf = $this->_objectManager->create('Magento\Shipping\Model\Order\Pdf\Packaging')->getPdf($shipment);
+            return $this->_fileFactory->create(
+                'packingslip' . $this->_objectManager->get(
+                    'Magento\Framework\Stdlib\DateTime\DateTime'
+                )->date(
+                    'Y-m-d_H-i-s'
+                ) . '.pdf',
+                $pdf->render(),
+                \Magento\Framework\App\Filesystem::VAR_DIR,
+                'application/pdf'
+            );
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/RemoveTrack.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/RemoveTrack.php
new file mode 100644
index 0000000000000000000000000000000000000000..aed7bc1b25f5ab93d912ea48288494492d66d507
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/RemoveTrack.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class RemoveTrack extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Remove tracking number from shipment
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $trackId = $this->getRequest()->getParam('track_id');
+        $track = $this->_objectManager->create('Magento\Sales\Model\Order\Shipment\Track')->load($trackId);
+        if ($track->getId()) {
+            try {
+                $this->_title->add(__('Shipments'));
+                $shipment = $this->shipmentLoader->load($this->_request);
+                if ($shipment) {
+                    $track->delete();
+
+                    $this->_view->loadLayout();
+                    $response = $this->_view->getLayout()->getBlock('shipment_tracking')->toHtml();
+                } else {
+                    $response = array(
+                        'error' => true,
+                        'message' => __('Cannot initialize shipment for delete tracking number.')
+                    );
+                }
+            } catch (\Exception $e) {
+                $response = array('error' => true, 'message' => __('Cannot delete tracking number.'));
+            }
+        } else {
+            $response = array('error' => true, 'message' => __('Cannot load track with retrieving identifier.'));
+        }
+        if (is_array($response)) {
+            $response = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($response);
+            $this->getResponse()->representJson($response);
+        } else {
+            $this->getResponse()->setBody($response);
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..a8e1ef0036758bd5e02f15e007d0a5fb9e9cb64c
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Save.php
@@ -0,0 +1,164 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class Save extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @var \Magento\Shipping\Model\Shipping\LabelGenerator
+     */
+    protected $labelGenerator;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     * @param \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader,
+        \Magento\Shipping\Model\Shipping\LabelGenerator $labelGenerator
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        $this->labelGenerator = $labelGenerator;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Save shipment and order in one transaction
+     *
+     * @param \Magento\Sales\Model\Order\Shipment $shipment
+     * @return $this
+     */
+    protected function _saveShipment($shipment)
+    {
+        $shipment->getOrder()->setIsInProcess(true);
+        $transactionSave = $this->_objectManager->create(
+            'Magento\Framework\DB\Transaction'
+        )->addObject(
+            $shipment
+        )->addObject(
+            $shipment->getOrder()
+        )->save();
+
+        return $this;
+    }
+
+    /**
+     * Save shipment
+     * We can save only new shipment. Existing shipments are not editable
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $data = $this->getRequest()->getPost('shipment');
+        if (!empty($data['comment_text'])) {
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setCommentText($data['comment_text']);
+        }
+
+        try {
+            $shipment = $this->shipmentLoader->load($this->_request);
+            if (!$shipment) {
+                $this->_forward('noroute');
+                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->getOrder()->setCustomerNoteNotify(!empty($data['send_email']));
+            $responseAjax = new \Magento\Framework\Object();
+            $isNeedCreateLabel = isset($data['create_shipping_label']) && $data['create_shipping_label'];
+
+            if ($isNeedCreateLabel && $this->labelGenerator->create($shipment, $this->_request)) {
+                $responseAjax->setOk(true);
+            }
+
+            $this->_saveShipment($shipment);
+
+            $shipment->sendEmail(!empty($data['send_email']), $comment);
+
+            $shipmentCreatedMessage = __('The shipment has been created.');
+            $labelCreatedMessage = __('You created the shipping label.');
+
+            $this->messageManager->addSuccess(
+                $isNeedCreateLabel ? $shipmentCreatedMessage . ' ' . $labelCreatedMessage : $shipmentCreatedMessage
+            );
+            $this->_objectManager->get('Magento\Backend\Model\Session')->getCommentText(true);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            if ($isNeedCreateLabel) {
+                $responseAjax->setError(true);
+                $responseAjax->setMessage($e->getMessage());
+            } else {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
+            }
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            if ($isNeedCreateLabel) {
+                $responseAjax->setError(true);
+                $responseAjax->setMessage(__('An error occurred while creating shipping label.'));
+            } else {
+                $this->messageManager->addError(__('Cannot save shipment.'));
+                $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
+            }
+        }
+        if ($isNeedCreateLabel) {
+            $this->getResponse()->representJson($responseAjax->toJson());
+        } else {
+            $this->_redirect('sales/order/view', array('order_id' => $shipment->getOrderId()));
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..88254f46fa31a0e1d749f23bbfa7c203f84adb57
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/Start.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+class Start extends \Magento\Backend\App\Action
+{
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Start create shipment action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /**
+         * Clear old values for shipment qty's
+         */
+        $this->_redirect('*/*/new', array('order_id' => $this->getRequest()->getParam('order_id')));
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php
new file mode 100644
index 0000000000000000000000000000000000000000..50c03f4d561744f3419d25cb21cf2ac6e347578c
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/Shipment/View.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order\Shipment;
+
+use \Magento\Backend\App\Action;
+
+class View extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader
+     */
+    protected $shipmentLoader;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Shipping\Controller\Adminhtml\Order\ShipmentLoader $shipmentLoader
+    ) {
+        $this->shipmentLoader = $shipmentLoader;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return $this->_authorization->isAllowed('Magento_Sales::shipment');
+    }
+
+    /**
+     * Shipment information page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Shipments'));
+        $shipment = $this->shipmentLoader->load($this->_request);
+        if ($shipment) {
+            $this->_title->add("#" . $shipment->getIncrementId());
+            $this->_view->loadLayout();
+            $this->_view->getLayout()->getBlock(
+                'sales_shipment_view'
+            )->updateBackButtonUrl(
+                $this->getRequest()->getParam('come_from')
+            );
+            $this->_setActiveMenu('Magento_Sales::sales_order');
+            $this->_view->renderLayout();
+        } else {
+            $this->_forward('noroute');
+        }
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php
new file mode 100644
index 0000000000000000000000000000000000000000..6cc1afeda48fa055462d1f5062ddb3681d3f5f26
--- /dev/null
+++ b/app/code/Magento/Shipping/Controller/Adminhtml/Order/ShipmentLoader.php
@@ -0,0 +1,158 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Controller\Adminhtml\Order;
+
+use Magento\Framework\App\RequestInterface;
+
+class ShipmentLoader
+{
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @var \Magento\Sales\Model\Order\ShipmentFactory
+     */
+    protected $shipmentFactory;
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @var \Magento\Sales\Model\Service\OrderFactory
+     */
+    protected $orderServiceFactory;
+
+    /**
+     * @var \Magento\Sales\Model\Order\Shipment\TrackFactory
+     */
+    protected $trackFactory;
+
+    /**
+     * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Sales\Model\Service\OrderFactory $orderServiceFactory
+     * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory
+     */
+    public function __construct(
+        \Magento\Framework\Message\ManagerInterface $messageManager,
+        \Magento\Framework\Registry $registry,
+        \Magento\Sales\Model\Order\ShipmentFactory $shipmentFactory,
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Sales\Model\Service\OrderFactory $orderServiceFactory,
+        \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory
+    ) {
+        $this->messageManager = $messageManager;
+        $this->registry = $registry;
+        $this->shipmentFactory = $shipmentFactory;
+        $this->orderFactory = $orderFactory;
+        $this->orderServiceFactory = $orderServiceFactory;
+        $this->trackFactory = $trackFactory;
+    }
+
+    /**
+     * Initialize shipment items QTY
+     *
+     * @param RequestInterface $request
+     * @return array
+     */
+    protected function _getItemQtys(RequestInterface $request)
+    {
+        $data = $request->getParam('shipment');
+        if (isset($data['items'])) {
+            $qtys = $data['items'];
+        } else {
+            $qtys = array();
+        }
+        return $qtys;
+    }
+
+    /**
+     * Initialize shipment model instance
+     *
+     * @param RequestInterface $request
+     * @return bool|\Magento\Sales\Model\Order\Shipment
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function load(RequestInterface $request)
+    {
+        $shipment = false;
+        $shipmentId = $request->getParam('shipment_id');
+        $orderId = $request->getParam('order_id');
+        if ($shipmentId) {
+            $shipment = $this->shipmentFactory->create()->load($shipmentId);
+        } elseif ($orderId) {
+            $order = $this->orderFactory->create()->load($orderId);
+
+            /**
+             * Check order existing
+             */
+            if (!$order->getId()) {
+                $this->messageManager->addError(__('The order no longer exists.'));
+                return false;
+            }
+            /**
+             * Check shipment is available to create separate from invoice
+             */
+            if ($order->getForcedShipmentWithInvoice()) {
+                $this->messageManager->addError(__('Cannot do shipment for the order separately from invoice.'));
+                return false;
+            }
+            /**
+             * Check shipment create availability
+             */
+            if (!$order->canShip()) {
+                $this->messageManager->addError(__('Cannot do shipment for the order.'));
+                return false;
+            }
+            $savedQtys = $this->_getItemQtys($request);
+            $shipment = $this->orderServiceFactory->create(array('order' => $order))->prepareShipment($savedQtys);
+
+            $tracks = $request->getPost('tracking');
+            if ($tracks) {
+                foreach ($tracks as $data) {
+                    if (empty($data['number'])) {
+                        throw new \Magento\Framework\Model\Exception(__('Please enter a tracking number.'));
+                    }
+                    $track = $this->trackFactory->create()->addData($data);
+                    $shipment->addTrack($track);
+                }
+            }
+        }
+
+        $this->registry->register('current_shipment', $shipment);
+        return $shipment;
+    }
+}
diff --git a/app/code/Magento/Shipping/Controller/Tracking.php b/app/code/Magento/Shipping/Controller/Tracking/Popup.php
similarity index 92%
rename from app/code/Magento/Shipping/Controller/Tracking.php
rename to app/code/Magento/Shipping/Controller/Tracking/Popup.php
index a97e7dbbfa986500ed8bae72aa2f5381e34b849d..0e41a03e6d1bbd2dc4541060b7999fc19e8d1446 100644
--- a/app/code/Magento/Shipping/Controller/Tracking.php
+++ b/app/code/Magento/Shipping/Controller/Tracking/Popup.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,14 +22,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Shipping\Controller;
+namespace Magento\Shipping\Controller\Tracking;
 
-use Magento\Framework\App\Action\NotFoundException;
+use \Magento\Framework\App\Action\NotFoundException;
 
-/**
- * Sales orders controller
- */
-class Tracking extends \Magento\Framework\App\Action\Action
+class Popup extends \Magento\Framework\App\Action\Action
 {
     /**
      * Core registry
@@ -72,7 +70,7 @@ class Tracking extends \Magento\Framework\App\Action\Action
      * @return void
      * @throws NotFoundException
      */
-    public function popupAction()
+    public function execute()
     {
         $shippingInfoModel = $this->_shippingInfoFactory->create()->loadByHash($this->getRequest()->getParam('hash'));
         $this->_coreRegistry->register('current_shipping_info', $shippingInfoModel);
diff --git a/app/code/Magento/Shipping/Model/Shipping/LabelGenerator.php b/app/code/Magento/Shipping/Model/Shipping/LabelGenerator.php
new file mode 100644
index 0000000000000000000000000000000000000000..235d590812b8878490ac2cde260d9efd82229d10
--- /dev/null
+++ b/app/code/Magento/Shipping/Model/Shipping/LabelGenerator.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Shipping\Model\Shipping;
+
+use Magento\Framework\App\RequestInterface;
+
+class LabelGenerator
+{
+    /**
+     * @var \Magento\Shipping\Model\CarrierFactory
+     */
+    protected $_carrierFactory;
+
+    /**
+     * @var \Magento\Shipping\Model\Shipping\LabelsFactory
+     */
+    protected $labelFactory;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $scopeConfig;
+
+    /**
+     * @var \Magento\Sales\Model\Order\Shipment\TrackFactory
+     */
+    protected $trackFactory;
+
+    /**
+     * @var \Magento\Framework\App\Filesystem
+     */
+    protected $filesystem;
+
+    /**
+     * @param \Magento\Shipping\Model\CarrierFactory $carrierFactory
+     * @param LabelsFactory $labelFactory
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory
+     * @param \Magento\Framework\App\Filesystem $filesystem
+     */
+    public function __construct(
+        \Magento\Shipping\Model\CarrierFactory $carrierFactory,
+        \Magento\Shipping\Model\Shipping\LabelsFactory $labelFactory,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Sales\Model\Order\Shipment\TrackFactory $trackFactory,
+        \Magento\Framework\App\Filesystem $filesystem
+    ) {
+        $this->_carrierFactory = $carrierFactory;
+        $this->labelFactory = $labelFactory;
+        $this->scopeConfig = $scopeConfig;
+        $this->trackFactory = $trackFactory;
+        $this->filesystem = $filesystem;
+    }
+
+    /**
+     * @param \Magento\Sales\Model\Order\Shipment $shipment
+     * @param RequestInterface $request
+     * @return bool
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function create(\Magento\Sales\Model\Order\Shipment $shipment, RequestInterface $request)
+    {
+        if (!$shipment) {
+            return false;
+        }
+        $order = $shipment->getOrder();
+        $carrier = $this->_carrierFactory->create($order->getShippingMethod(true)->getCarrierCode());
+        if (!$carrier->isShippingLabelsAvailable()) {
+            return false;
+        }
+        $shipment->setPackages($request->getParam('packages'));
+        $response = $this->labelFactory->create()->requestToShipment(
+            $shipment
+        );
+        if ($response->hasErrors()) {
+            throw new \Magento\Framework\Model\Exception($response->getErrors());
+        }
+        if (!$response->hasInfo()) {
+            return false;
+        }
+        $labelsContent = array();
+        $trackingNumbers = array();
+        $info = $response->getInfo();
+        foreach ($info as $inf) {
+            if (!empty($inf['tracking_number']) && !empty($inf['label_content'])) {
+                $labelsContent[] = $inf['label_content'];
+                $trackingNumbers[] = $inf['tracking_number'];
+            }
+        }
+        $outputPdf = $this->combineLabelsPdf($labelsContent);
+        $shipment->setShippingLabel($outputPdf->render());
+        $carrierCode = $carrier->getCarrierCode();
+        $carrierTitle = $this->scopeConfig->getValue(
+            'carriers/' . $carrierCode . '/title',
+            \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
+            $shipment->getStoreId()
+        );
+        if ($trackingNumbers) {
+            foreach ($trackingNumbers as $trackingNumber) {
+                $track = $this->trackFactory->create()
+                    ->setNumber(
+                        $trackingNumber
+                    )->setCarrierCode(
+                        $carrierCode
+                    )->setTitle(
+                        $carrierTitle
+                    );
+                $shipment->addTrack($track);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Combine array of labels as instance PDF
+     *
+     * @param array $labelsContent
+     * @return \Zend_Pdf
+     */
+    public function combineLabelsPdf(array $labelsContent)
+    {
+        $outputPdf = new \Zend_Pdf();
+        foreach ($labelsContent as $content) {
+            if (stripos($content, '%PDF-') !== false) {
+                $pdfLabel = \Zend_Pdf::parse($content);
+                foreach ($pdfLabel->pages as $page) {
+                    $outputPdf->pages[] = clone $page;
+                }
+            } else {
+                $page = $this->createPdfPageFromImageString($content);
+                if ($page) {
+                    $outputPdf->pages[] = $page;
+                }
+            }
+        }
+        return $outputPdf;
+    }
+
+    /**
+     * Create \Zend_Pdf_Page instance with image from $imageString. Supports JPEG, PNG, GIF, WBMP, and GD2 formats.
+     *
+     * @param string $imageString
+     * @return \Zend_Pdf_Page|false
+     */
+    public function createPdfPageFromImageString($imageString)
+    {
+        /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
+        $directory = $this->filesystem->getDirectoryWrite(
+            \Magento\Framework\App\Filesystem::TMP_DIR
+        );
+        $directory->create();
+        $image = imagecreatefromstring($imageString);
+        if (!$image) {
+            return false;
+        }
+
+        $xSize = imagesx($image);
+        $ySize = imagesy($image);
+        $page = new \Zend_Pdf_Page($xSize, $ySize);
+
+        imageinterlace($image, 0);
+        $tmpFileName = $directory->getAbsolutePath(
+            'shipping_labels_' . uniqid(\Magento\Framework\Math\Random::getRandomNumber()) . time() . '.png'
+        );
+        imagepng($image, $tmpFileName);
+        $pdfImage = \Zend_Pdf_Image::imageWithPath($tmpFileName);
+        $page->drawImage($pdfImage, 0, 0, $xSize, $ySize);
+        $directory->delete($directory->getRelativePath($tmpFileName));
+        return $page;
+    }
+}
diff --git a/app/code/Magento/Sitemap/Block/Adminhtml/Edit.php b/app/code/Magento/Sitemap/Block/Adminhtml/Edit.php
index 660c79d819616884925e54c6368cdf62b805133c..7f3cfd75167fda6e390b8a35ffa6bb271fdd9b6f 100644
--- a/app/code/Magento/Sitemap/Block/Adminhtml/Edit.php
+++ b/app/code/Magento/Sitemap/Block/Adminhtml/Edit.php
@@ -38,12 +38,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -64,7 +64,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_addButton(
+        $this->buttonList->add(
             'generate',
             array(
                 'label' => __('Save & Generate'),
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap.php
index 4768b9d09a2471a3d291bca7b4dd93160dfdd3e1..f8dcccd01cc7518d6cec16b5de47de18d6dc8d65 100644
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap.php
@@ -23,30 +23,11 @@
  */
 namespace Magento\Sitemap\Controller\Adminhtml;
 
-use Magento\Backend\App\Action;
-
 /**
  * XML sitemap controller
  */
 class Sitemap extends \Magento\Backend\App\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
     /**
      * Init actions
      *
@@ -68,250 +49,6 @@ class Sitemap extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Site Map'));
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new sitemap
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        // the same form is used to create and edit
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit sitemap
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Site Map'));
-
-        // 1. Get ID and create model
-        $id = $this->getRequest()->getParam('sitemap_id');
-        $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
-
-        // 2. Initial checking
-        if ($id) {
-            $model->load($id);
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This sitemap no longer exists.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            }
-        }
-
-        $this->_title->add($model->getId() ? $model->getSitemapFilename() : __('New Site Map'));
-
-        // 3. Set entered data if was error when we do save
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
-        if (!empty($data)) {
-            $model->setData($data);
-        }
-
-        // 4. Register model to use later in blocks
-        $this->_coreRegistry->register('sitemap_sitemap', $model);
-
-        // 5. Build edit form
-        $this->_initAction()->_addBreadcrumb(
-            $id ? __('Edit Sitemap') : __('New Sitemap'),
-            $id ? __('Edit Sitemap') : __('New Sitemap')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Sitemap\Block\Adminhtml\Edit')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        // check if data sent
-        $data = $this->getRequest()->getPost();
-        if ($data) {
-            // init model and set data
-            /** @var \Magento\Sitemap\Model\Sitemap $model */
-            $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
-
-            //validate path to generate
-            if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) {
-                $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename'];
-                /** @var $validator \Magento\Core\Model\File\Validator\AvailablePath */
-                $validator = $this->_objectManager->create('Magento\Core\Model\File\Validator\AvailablePath');
-                /** @var $helper \Magento\Catalog\Helper\Catalog */
-                $helper = $this->_objectManager->get('Magento\Catalog\Helper\Catalog');
-                $validator->setPaths($helper->getSitemapValidPaths());
-                if (!$validator->isValid($path)) {
-                    foreach ($validator->getMessages() as $message) {
-                        $this->messageManager->addError($message);
-                    }
-                    // save data in session
-                    $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
-                    // redirect to edit form
-                    $this->_redirect(
-                        'adminhtml/*/edit',
-                        array('sitemap_id' => $this->getRequest()->getParam('sitemap_id'))
-                    );
-                    return;
-                }
-            }
-
-            /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
-            $directory = $this->_objectManager->get(
-                'Magento\Framework\App\Filesystem'
-            )->getDirectoryWrite(
-                \Magento\Framework\App\Filesystem::ROOT_DIR
-            );
-
-            if ($this->getRequest()->getParam('sitemap_id')) {
-                $model->load($this->getRequest()->getParam('sitemap_id'));
-                $fileName = $model->getSitemapFilename();
-
-                $path = $model->getSitemapPath() . '/' . $fileName;
-                if ($fileName && $directory->isFile($path)) {
-                    $directory->delete($path);
-                }
-            }
-
-            $model->setData($data);
-
-            // try to save it
-            try {
-                // save the data
-                $model->save();
-                // display success message
-                $this->messageManager->addSuccess(__('The sitemap has been saved.'));
-                // clear previously saved data from session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
-
-                // check if 'Save and Continue'
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('adminhtml/*/edit', array('sitemap_id' => $model->getId()));
-                    return;
-                }
-                // go to grid or forward to generate action
-                if ($this->getRequest()->getParam('generate')) {
-                    $this->getRequest()->setParam('sitemap_id', $model->getId());
-                    $this->_forward('generate');
-                    return;
-                }
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (\Exception $e) {
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // save data in session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
-                // redirect to edit form
-                $this->_redirect(
-                    'adminhtml/*/edit',
-                    array('sitemap_id' => $this->getRequest()->getParam('sitemap_id'))
-                );
-                return;
-            }
-        }
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
-        $directory = $this->_objectManager->get(
-            'Magento\Framework\App\Filesystem'
-        )->getDirectoryWrite(
-            \Magento\Framework\App\Filesystem::ROOT_DIR
-        );
-
-        // check if we know what should be deleted
-        $id = $this->getRequest()->getParam('sitemap_id');
-        if ($id) {
-            try {
-                // init model and delete
-                $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
-                $model->setId($id);
-                // init and load sitemap model
-
-                /* @var $sitemap \Magento\Sitemap\Model\Sitemap */
-                $model->load($id);
-                // delete file
-                $path = $directory->getRelativePath($model->getPreparedFilename());
-                if ($model->getSitemapFilename() && $directory->isFile($path)) {
-                    $directory->delete($path);
-                }
-                $model->delete();
-                // display success message
-                $this->messageManager->addSuccess(__('The sitemap has been deleted.'));
-                // go to grid
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (\Exception $e) {
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // go back to edit form
-                $this->_redirect('adminhtml/*/edit', array('sitemap_id' => $id));
-                return;
-            }
-        }
-        // display error message
-        $this->messageManager->addError(__('We can\'t find a sitemap to delete.'));
-        // go to grid
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Generate sitemap
-     *
-     * @return void
-     */
-    public function generateAction()
-    {
-        // init and load sitemap model
-        $id = $this->getRequest()->getParam('sitemap_id');
-        $sitemap = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
-        /* @var $sitemap \Magento\Sitemap\Model\Sitemap */
-        $sitemap->load($id);
-        // if sitemap record exists
-        if ($sitemap->getId()) {
-            try {
-                $sitemap->generateXml();
-
-                $this->messageManager->addSuccess(
-                    __('The sitemap "%1" has been generated.', $sitemap->getSitemapFilename())
-                );
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addException($e, __('Something went wrong generating the sitemap.'));
-            }
-        } else {
-            $this->messageManager->addError(__('We can\'t find a sitemap to generate.'));
-        }
-
-        // go to grid
-        $this->_redirect('adminhtml/*/');
-    }
-
     /**
      * Check the permission to run it
      *
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d1c25ac838ef9fdc5a86f7bfb957fba6b5bc171
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Delete.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+use \Magento\Backend\App\Action;
+
+class Delete extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
+        $directory = $this->_objectManager->get(
+            'Magento\Framework\App\Filesystem'
+        )->getDirectoryWrite(
+            \Magento\Framework\App\Filesystem::ROOT_DIR
+        );
+
+        // check if we know what should be deleted
+        $id = $this->getRequest()->getParam('sitemap_id');
+        if ($id) {
+            try {
+                // init model and delete
+                $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
+                $model->setId($id);
+                // init and load sitemap model
+
+                /* @var $sitemap \Magento\Sitemap\Model\Sitemap */
+                $model->load($id);
+                // delete file
+                $path = $directory->getRelativePath($model->getPreparedFilename());
+                if ($model->getSitemapFilename() && $directory->isFile($path)) {
+                    $directory->delete($path);
+                }
+                $model->delete();
+                // display success message
+                $this->messageManager->addSuccess(__('The sitemap has been deleted.'));
+                // go to grid
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (\Exception $e) {
+                // display error message
+                $this->messageManager->addError($e->getMessage());
+                // go back to edit form
+                $this->_redirect('adminhtml/*/edit', array('sitemap_id' => $id));
+                return;
+            }
+        }
+        // display error message
+        $this->messageManager->addError(__('We can\'t find a sitemap to delete.'));
+        // go to grid
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1e85cff88d1bd6041a15a116e5245a6ddc0fb6c
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Edit.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+class Edit extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
+    {
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Edit sitemap
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Site Map'));
+
+        // 1. Get ID and create model
+        $id = $this->getRequest()->getParam('sitemap_id');
+        $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
+
+        // 2. Initial checking
+        if ($id) {
+            $model->load($id);
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This sitemap no longer exists.'));
+                $this->_redirect('adminhtml/*/');
+                return;
+            }
+        }
+
+        $this->_title->add($model->getId() ? $model->getSitemapFilename() : __('New Site Map'));
+
+        // 3. Set entered data if was error when we do save
+        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true);
+        if (!empty($data)) {
+            $model->setData($data);
+        }
+
+        // 4. Register model to use later in blocks
+        $this->_coreRegistry->register('sitemap_sitemap', $model);
+
+        // 5. Build edit form
+        $this->_initAction()->_addBreadcrumb(
+            $id ? __('Edit Sitemap') : __('New Sitemap'),
+            $id ? __('Edit Sitemap') : __('New Sitemap')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Sitemap\Block\Adminhtml\Edit')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c8593529dd34636b0c024ffdb46f0b5bf35215f
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Generate.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+use \Magento\Backend\App\Action;
+
+class Generate extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Generate sitemap
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // init and load sitemap model
+        $id = $this->getRequest()->getParam('sitemap_id');
+        $sitemap = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
+        /* @var $sitemap \Magento\Sitemap\Model\Sitemap */
+        $sitemap->load($id);
+        // if sitemap record exists
+        if ($sitemap->getId()) {
+            try {
+                $sitemap->generateXml();
+
+                $this->messageManager->addSuccess(
+                    __('The sitemap "%1" has been generated.', $sitemap->getSitemapFilename())
+                );
+            } catch (\Magento\Framework\Model\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Something went wrong generating the sitemap.'));
+            }
+        } else {
+            $this->messageManager->addError(__('We can\'t find a sitemap to generate.'));
+        }
+
+        // go to grid
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..c95861f946fbf2eb867ec38287d85efff6ed8a80
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+use \Magento\Backend\App\Action;
+
+class Index extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Site Map'));
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/NewAction.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..6c3e96e9284676f6d603820322ebfa5ce4182fb9
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/NewAction.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+use \Magento\Backend\App\Action;
+
+class NewAction extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Create new sitemap
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // the same form is used to create and edit
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5dce81be688f6708f37303d41ff8572456f70b3
--- /dev/null
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
+
+use \Magento\Backend\App\Action;
+
+class Save extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
+{
+    /**
+     * Save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // check if data sent
+        $data = $this->getRequest()->getPost();
+        if ($data) {
+            // init model and set data
+            /** @var \Magento\Sitemap\Model\Sitemap $model */
+            $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
+
+            //validate path to generate
+            if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) {
+                $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename'];
+                /** @var $validator \Magento\Core\Model\File\Validator\AvailablePath */
+                $validator = $this->_objectManager->create('Magento\Core\Model\File\Validator\AvailablePath');
+                /** @var $helper \Magento\Catalog\Helper\Catalog */
+                $helper = $this->_objectManager->get('Magento\Catalog\Helper\Catalog');
+                $validator->setPaths($helper->getSitemapValidPaths());
+                if (!$validator->isValid($path)) {
+                    foreach ($validator->getMessages() as $message) {
+                        $this->messageManager->addError($message);
+                    }
+                    // save data in session
+                    $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
+                    // redirect to edit form
+                    $this->_redirect(
+                        'adminhtml/*/edit',
+                        array('sitemap_id' => $this->getRequest()->getParam('sitemap_id'))
+                    );
+                    return;
+                }
+            }
+
+            /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
+            $directory = $this->_objectManager->get(
+                'Magento\Framework\App\Filesystem'
+            )->getDirectoryWrite(
+                \Magento\Framework\App\Filesystem::ROOT_DIR
+            );
+
+            if ($this->getRequest()->getParam('sitemap_id')) {
+                $model->load($this->getRequest()->getParam('sitemap_id'));
+                $fileName = $model->getSitemapFilename();
+
+                $path = $model->getSitemapPath() . '/' . $fileName;
+                if ($fileName && $directory->isFile($path)) {
+                    $directory->delete($path);
+                }
+            }
+
+            $model->setData($data);
+
+            // try to save it
+            try {
+                // save the data
+                $model->save();
+                // display success message
+                $this->messageManager->addSuccess(__('The sitemap has been saved.'));
+                // clear previously saved data from session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+
+                // check if 'Save and Continue'
+                if ($this->getRequest()->getParam('back')) {
+                    $this->_redirect('adminhtml/*/edit', array('sitemap_id' => $model->getId()));
+                    return;
+                }
+                // go to grid or forward to generate action
+                if ($this->getRequest()->getParam('generate')) {
+                    $this->getRequest()->setParam('sitemap_id', $model->getId());
+                    $this->_forward('generate');
+                    return;
+                }
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (\Exception $e) {
+                // display error message
+                $this->messageManager->addError($e->getMessage());
+                // save data in session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
+                // redirect to edit form
+                $this->_redirect(
+                    'adminhtml/*/edit',
+                    array('sitemap_id' => $this->getRequest()->getParam('sitemap_id'))
+                );
+                return;
+            }
+        }
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
index 345511527f751560c94423620f27fc068681ff93..3f6db9c9b7040716abf50b4eb927fdbb74b09388 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Form.php
@@ -29,6 +29,9 @@
  */
 namespace Magento\Tax\Block\Adminhtml\Rate;
 
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Tax\Controller\RegistryConstants;
+
 class Form extends \Magento\Backend\Block\Widget\Form\Generic
 {
     const FORM_ELEMENT_ID = 'rate-form';
@@ -56,24 +59,24 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     protected $_fieldsetFactory;
 
     /**
-     * @var \Magento\Tax\Model\Calculation\RateFactory
+     * @var \Magento\Directory\Model\Config\Source\Country
      */
-    protected $_rateFactory;
+    protected $_country;
 
     /**
-     * @var \Magento\Tax\Model\Calculation\Rate
+     * @var \Magento\Directory\Model\RegionFactory
      */
-    protected $_rate;
+    protected $_regionFactory;
 
     /**
-     * @var \Magento\Directory\Model\Config\Source\Country
+     * @var \Magento\Tax\Service\V1\TaxRateServiceInterface
      */
-    protected $_country;
+    protected $_taxRateService;
 
     /**
-     * @var \Magento\Directory\Model\RegionFactory
+     * @var \Magento\Tax\Service\V1\Collection\TaxRateCollection
      */
-    protected $_regionFactory;
+    protected $_taxRateCollection;
 
     /**
      * @param \Magento\Backend\Block\Template\Context $context
@@ -82,9 +85,9 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      * @param \Magento\Directory\Model\RegionFactory $regionFactory
      * @param \Magento\Directory\Model\Config\Source\Country $country
      * @param \Magento\Tax\Block\Adminhtml\Rate\Title\FieldsetFactory $fieldsetFactory
-     * @param \Magento\Tax\Model\Calculation\RateFactory $rateFactory
-     * @param \Magento\Tax\Model\Calculation\Rate $rate
      * @param \Magento\Tax\Helper\Data $taxData
+     * @param \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService
+     * @param \Magento\Tax\Service\V1\Collection\TaxRateCollection $taxRateCollection
      * @param array $data
      */
     public function __construct(
@@ -94,17 +97,17 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         \Magento\Directory\Model\RegionFactory $regionFactory,
         \Magento\Directory\Model\Config\Source\Country $country,
         \Magento\Tax\Block\Adminhtml\Rate\Title\FieldsetFactory $fieldsetFactory,
-        \Magento\Tax\Model\Calculation\RateFactory $rateFactory,
-        \Magento\Tax\Model\Calculation\Rate $rate,
         \Magento\Tax\Helper\Data $taxData,
+        \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService,
+        \Magento\Tax\Service\V1\Collection\TaxRateCollection $taxRateCollection,
         array $data = array()
     ) {
         $this->_regionFactory = $regionFactory;
         $this->_country = $country;
         $this->_fieldsetFactory = $fieldsetFactory;
-        $this->_rateFactory = $rateFactory;
-        $this->_rate = $rate;
         $this->_taxData = $taxData;
+        $this->_taxRateService = $taxRateService;
+        $this->_taxRateCollection = $taxRateCollection;
         parent::__construct($context, $registry, $formFactory, $data);
     }
 
@@ -122,33 +125,46 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      */
     protected function _prepareForm()
     {
-        $rateObject = new \Magento\Framework\Object($this->_rate->getData());
+        $taxRateId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_TAX_RATE_ID);
+
+        try {
+            if ($taxRateId) {
+                $taxRateDataObject = $this->_taxRateService->getTaxRate($taxRateId);
+            }
+        } catch (NoSuchEntityException $e) {
+            /* tax rate not found */
+        }
+
+        $sessionFormValues = (array)$this->_coreRegistry->registry(RegistryConstants::CURRENT_TAX_RATE_FORM_DATA);
+        $formData = isset($taxRateDataObject) ? $this->extractTaxRateData($taxRateDataObject) : [];
+        $formData = array_merge($formData, $sessionFormValues);
+
+        if (isset($formData['zip_is_range']) && $formData['zip_is_range'] && !isset($formData['tax_postcode'])) {
+            $formData['tax_postcode'] = $formData['zip_from'] . '-' . $formData['zip_to'];
+        }
+
         /** @var \Magento\Framework\Data\Form $form */
         $form = $this->_formFactory->create();
 
         $countries = $this->_country->toOptionArray(false, 'US');
         unset($countries[0]);
 
-        if (!$rateObject->hasTaxCountryId()) {
-            $rateObject->setTaxCountryId(
-                $this->_scopeConfig->getValue(
-                    \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_COUNTRY,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
+        if (!isset($formData['tax_country_id'])) {
+            $formData['tax_country_id'] = $this->_scopeConfig->getValue(
+                \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_COUNTRY,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
             );
         }
 
-        if (!$rateObject->hasTaxRegionId()) {
-            $rateObject->setTaxRegionId(
-                $this->_scopeConfig->getValue(
-                    \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_REGION,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
+        if (!isset($formData['tax_region_id'])) {
+            $formData['tax_region_id'] = $this->_scopeConfig->getValue(
+                \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_REGION,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
             );
         }
 
         $regionCollection = $this->_regionFactory->create()->getCollection()->addCountryFilter(
-            $rateObject->getTaxCountryId()
+            $formData['tax_country_id']
         );
 
         $regions = $regionCollection->toOptionArray();
@@ -161,11 +177,11 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         $legend = $this->getShowLegend() ? __('Tax Rate Information') : '';
         $fieldset = $form->addFieldset('base_fieldset', array('legend' => $legend));
 
-        if ($rateObject->getTaxCalculationRateId() > 0) {
+        if (isset($formData['tax_calculation_rate_id']) && $formData['tax_calculation_rate_id'] > 0) {
             $fieldset->addField(
                 'tax_calculation_rate_id',
                 'hidden',
-                array('name' => 'tax_calculation_rate_id', 'value' => $rateObject->getTaxCalculationRateId())
+                array('name' => 'tax_calculation_rate_id', 'value' => $formData['tax_calculation_rate_id'])
             );
         }
 
@@ -187,12 +203,10 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
             array('name' => 'zip_is_range', 'label' => __('Zip/Post is Range'), 'value' => '1')
         );
 
-        if (!$rateObject->hasTaxPostcode()) {
-            $rateObject->setTaxPostcode(
-                $this->_scopeConfig->getValue(
-                    \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_POSTCODE,
-                    \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                )
+        if (!isset($formData['tax_postcode'])) {
+            $formData['tax_postcode'] = $this->_scopeConfig->getValue(
+                \Magento\Tax\Model\Config::CONFIG_XML_PATH_DEFAULT_POSTCODE,
+                \Magento\Store\Model\ScopeInterface::SCOPE_STORE
             );
         }
 
@@ -268,11 +282,10 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
             $form->addElement($this->_fieldsetFactory->create()->setLegend(__('Tax Titles')));
         }
 
-        $rateData = $rateObject->getData();
-        if ($rateObject->getZipIsRange()) {
-            list($rateData['zip_from'], $rateData['zip_to']) = explode('-', $rateData['tax_postcode']);
+        if (isset($formData['zip_is_range']) && $formData['zip_is_range']) {
+            list($formData['zip_from'], $formData['zip_to']) = explode('-', $formData['tax_postcode']);
         }
-        $form->setValues($rateData);
+        $form->setValues($formData);
         $this->setForm($form);
 
         $this->setChild(
@@ -291,19 +304,58 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     public function getRateCollection()
     {
         if ($this->getData('rate_collection') == null) {
-            $rateCollection = $this->_rateFactory->create()->getCollection()->joinRegionTable();
+            $items = $this->_taxRateCollection->getItems();
             $rates = array();
-
-            foreach ($rateCollection as $rate) {
-                $item = $rate->getData();
-                foreach ($rate->getTitles() as $title) {
-                    $item['title[' . $title->getStoreId() . ']'] = $title->getValue();
+            foreach ($items as $rate) {
+                $rateData = $rate->getData();
+                if (isset($rateData['titles'])) {
+                    foreach ($rateData['titles'] as $storeId => $value) {
+                        $rateData['title[' . $storeId . ']'] = $value;
+                    }
                 }
-                $rates[] = $item;
+                unset($rateData['titles']);
+                $rates[] = $rateData;
             }
 
             $this->setRateCollection($rates);
         }
         return $this->getData('rate_collection');
     }
+
+    /**
+     * Extract tax rate data in a format which is
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxRate $taxRate
+     * @return array
+     */
+    protected function extractTaxRateData($taxRate)
+    {
+        $zipRange = $taxRate->getZipRange();
+
+        $formData = [
+            'tax_calculation_rate_id' => $taxRate->getId(),
+            'tax_country_id' => $taxRate->getCountryId(),
+            'tax_region_id' => $taxRate->getRegionId(),
+            'tax_postcode' => $taxRate->getPostcode(),
+            'code' => $taxRate->getCode(),
+            'rate' => $taxRate->getPercentageRate(),
+            'zip_is_range' => false
+        ];
+
+        if ($zipRange) {
+            $formData['zip_is_range'] = true;
+            $formData['zip_from'] = $zipRange->getFrom();
+            $formData['zip_to'] = $zipRange->getTo();
+        }
+
+        if ($taxRate->getTitles()) {
+            $titleData = [];
+            foreach ($taxRate->getTitles() as $title) {
+                $titleData[] = [$title->getStoreId() => $title->getValue()];
+            }
+            $formData['title'] = $titleData;
+        }
+
+        return $formData;
+    }
 }
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
index 3605afe8faf1d5a949dc6f8d8c96eb99e44be33e..cbab483dcbdc9b083425e1272185793ae52a576a 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Title.php
@@ -22,14 +22,15 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Tax\Block\Adminhtml\Rate;
+
+use Magento\Tax\Controller\RegistryConstants;
 
 /**
  * Tax Rate Titles Renderer
  *
  * @author Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Tax\Block\Adminhtml\Rate;
-
 class Title extends \Magento\Framework\View\Element\Template
 {
     /**
@@ -43,40 +44,59 @@ class Title extends \Magento\Framework\View\Element\Template
     protected $_template = 'rate/title.phtml';
 
     /**
-     * @var \Magento\Tax\Model\Calculation\Rate
+     * @var \Magento\Store\Model\StoreFactory
      */
-    protected $_rate;
+    protected $_storeFactory;
 
     /**
-     * @var \Magento\Store\Model\StoreFactory
+     * @var \Magento\Framework\Registry
      */
-    protected $_storeFactory;
+    protected $_coreRegistry;
+
+    /**
+     * @var \Magento\Tax\Service\V1\TaxRateServiceInterface
+     */
+    protected $_taxRateService;
 
     /**
+     * Initialize dependencies
+     *
      * @param \Magento\Framework\View\Element\Template\Context $context
      * @param \Magento\Store\Model\StoreFactory $storeFactory
-     * @param \Magento\Tax\Model\Calculation\Rate $rate
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\Template\Context $context,
         \Magento\Store\Model\StoreFactory $storeFactory,
-        \Magento\Tax\Model\Calculation\Rate $rate,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService,
         array $data = array()
     ) {
-        $this->_rate = $rate;
+        $this->_coreRegistry = $coreRegistry;
+        $this->_taxRateService = $taxRateService;
         $this->_storeFactory = $storeFactory;
         parent::__construct($context, $data);
     }
 
     /**
+     * Return the tax rate titles associated with a store view.
+     *
      * @return array
      */
     public function getTitles()
     {
         if (is_null($this->_titles)) {
             $this->_titles = array();
-            $titles = $this->_rate->getTitles();
+
+            $taxRateId = $this->_coreRegistry->registry(RegistryConstants::CURRENT_TAX_RATE_ID);
+            $titles = array();
+            if ($taxRateId) {
+                $rate = $this->_taxRateService->getTaxRate($taxRateId);
+                $titles = $rate->getTitles();
+            }
+
             foreach ($titles as $title) {
                 $this->_titles[$title->getStoreId()] = $title->getValue();
             }
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
index 043c5a58f6e8220d9bbadaf3d377ed3e6e8dbc4f..8abd0d8cc53177c320b8a984960d5d2ed81a8f70 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Add.php
@@ -29,27 +29,92 @@
  */
 namespace Magento\Tax\Block\Adminhtml\Rate\Toolbar;
 
-class Add extends \Magento\Backend\Block\Template
+use Magento\Framework\View\Element\Template;
+
+class Add extends \Magento\Backend\Block\Template implements \Magento\Backend\Block\Widget\ContainerInterface
 {
     /**
      * @var string
      */
     protected $_template = 'toolbar/rate/add.phtml';
 
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    protected $toolbar;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @param \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList,
+        \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar,
+        array $data = array()
+    ) {
+        $this->buttonList = $buttonList;
+        $this->toolbar = $toolbar;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * {$@inheritdoc}
+     */
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    {
+        $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
+        return $this;
+    }
+
+    /**
+     * {$@inheritdoc}
+     */
+    public function removeButton($buttonId)
+    {
+        $this->buttonList->remove($buttonId);
+        return $this;
+    }
+
     /**
      * @return $this
      */
     protected function _prepareLayout()
     {
-        $this->getToolbar()->addChild(
-            'addButton',
-            'Magento\Backend\Block\Widget\Button',
+        $this->buttonList->add(
+            'add',
             array(
                 'label' => __('Add New Tax Rate'),
                 'onclick' => 'window.location.href=\'' . $this->getUrl('tax/rate/add') . '\'',
                 'class' => 'add primary add-tax-rate'
             )
         );
+
+        $this->toolbar->pushButtons($this, $this->buttonList);
         return parent::_prepareLayout();
     }
+
+    /**
+     * {$@inheritdoc}
+     */
+    public function updateButton($buttonId, $key, $data)
+    {
+        $this->buttonList->update($buttonId, $key, $data);
+        return $this;
+    }
+
+    /**
+     * {$@inheritdoc}
+     */
+    public function canRender(\Magento\Backend\Block\Widget\Button\Item $item)
+    {
+        return !$item->isDeleted();
+    }
 }
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
index 69f736d91e39c96e9fea1ed664949d55932a0d53..4e4614eda81448ac1a35394272e346ef6290a341 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rate/Toolbar/Save.php
@@ -29,13 +29,40 @@
  */
 namespace Magento\Tax\Block\Adminhtml\Rate\Toolbar;
 
-class Save extends \Magento\Backend\Block\Template
+class Save extends \Magento\Backend\Block\Template implements \Magento\Backend\Block\Widget\ContainerInterface
 {
     /**
      * @var string
      */
     protected $_template = 'toolbar/rate/save.phtml';
 
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ButtonList
+     */
+    protected $buttonList;
+
+    /**
+     * @var \Magento\Backend\Block\Widget\Button\ToolbarInterface
+     */
+    protected $toolbar;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Button\ButtonList $buttonList
+     * @param \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Button\ButtonList $buttonList,
+        \Magento\Backend\Block\Widget\Button\ToolbarInterface $toolbar,
+        array $data = array()
+    ) {
+        $this->buttonList = $buttonList;
+        $this->toolbar = $toolbar;
+        parent::__construct($context, $data);
+    }
+
     /**
      * @return void
      */
@@ -45,14 +72,56 @@ class Save extends \Magento\Backend\Block\Template
         $this->assign('createUrl', $this->getUrl('tax/rate/save'));
     }
 
+
+    /**
+     * Public wrapper for the button list
+     *
+     * @param string $buttonId
+     * @param array $data
+     * @param integer $level
+     * @param integer $sortOrder
+     * @param string|null $region That button should be displayed in ('toolbar', 'header', 'footer', null)
+     * @return $this
+     */
+    public function addButton($buttonId, $data, $level = 0, $sortOrder = 0, $region = 'toolbar')
+    {
+        $this->buttonList->add($buttonId, $data, $level, $sortOrder, $region);
+        return $this;
+    }
+
+    /**
+     * Public wrapper for the button list
+     *
+     * @param string $buttonId
+     * @return $this
+     */
+    public function removeButton($buttonId)
+    {
+        $this->buttonList->remove($buttonId);
+        return $this;
+    }
+
+    /**
+     * Public wrapper for protected _updateButton method
+     *
+     * @param string $buttonId
+     * @param string|null $key
+     * @param string $data
+     * @return $this
+     */
+    public function updateButton($buttonId, $key, $data)
+    {
+        $this->buttonList->update($buttonId, $key, $data);
+        return $this;
+    }
+
     /**
      * @return $this
      */
     protected function _prepareLayout()
     {
-        $this->getToolbar()->addChild(
-            'backButton',
-            'Magento\Backend\Block\Widget\Button',
+        $this->buttonList->add(
+            'back',
             array(
                 'label' => __('Back'),
                 'onclick' => 'window.location.href=\'' . $this->getUrl('tax/*/') . '\'',
@@ -60,17 +129,15 @@ class Save extends \Magento\Backend\Block\Template
             )
         );
 
-        $this->getToolbar()->addChild(
-            'resetButton',
-            'Magento\Backend\Block\Widget\Button',
+        $this->buttonList->add(
+            'reset',
             array('label' => __('Reset'), 'onclick' => 'window.location.reload()', 'class' => 'reset')
         );
 
         $rate = intval($this->getRequest()->getParam('rate'));
         if ($rate) {
-            $this->getToolbar()->addChild(
-                'deleteButton',
-                'Magento\Backend\Block\Widget\Button',
+            $this->buttonList->add(
+                'delete',
                 array(
                     'label' => __('Delete Rate'),
                     'onclick' => 'deleteConfirm(\'' . __(
@@ -84,9 +151,8 @@ class Save extends \Magento\Backend\Block\Template
             );
         }
 
-        $this->getToolbar()->addChild(
-            'saveButton',
-            'Magento\Backend\Block\Widget\Button',
+        $this->buttonList->add(
+            'save',
             array(
                 'label' => __('Save Rate'),
                 'class' => 'save primary save-rate',
@@ -95,7 +161,18 @@ class Save extends \Magento\Backend\Block\Template
                 )
             )
         );
-
+        $this->toolbar->pushButtons($this, $this->buttonList);
         return parent::_prepareLayout();
     }
+
+    /**
+     * Check whether button rendering is allowed in current context
+     *
+     * @param \Magento\Backend\Block\Widget\Button\Item $item
+     * @return bool
+     */
+    public function canRender(\Magento\Backend\Block\Widget\Button\Item $item)
+    {
+        return !$item->isDeleted();
+    }
 }
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit.php b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit.php
index 20c855b2f12dc4da666bc08ce4bb42ad49111502..b19c2449571fcaf8742dd9bb8b2b81d56116c075 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit.php
@@ -37,12 +37,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -63,10 +63,10 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save Rule'));
-        $this->_updateButton('delete', 'label', __('Delete Rule'));
+        $this->buttonList->update('save', 'label', __('Save Rule'));
+        $this->buttonList->update('delete', 'label', __('Delete Rule'));
 
-        $this->_addButton(
+        $this->buttonList->add(
             'save_and_continue',
             array(
                 'label' => __('Save and Continue Edit'),
@@ -78,18 +78,4 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
             10
         );
     }
-
-    /**
-     * Get Header text
-     *
-     * @return string
-     */
-    public function getHeaderText()
-    {
-        if ($this->_coreRegistry->registry('tax_rule')->getId()) {
-            return __("Edit Rule");
-        } else {
-            return __('New Rule');
-        }
-    }
 }
diff --git a/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
index b5c6352852ab5a325f3508c447184d82f0854d81..4ed1abc1ac2598dfe656d3c3f6a3cb18827b0800 100644
--- a/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
+++ b/app/code/Magento/Tax/Block/Adminhtml/Rule/Edit/Form.php
@@ -27,34 +27,76 @@
  */
 namespace Magento\Tax\Block\Adminhtml\Rule\Edit;
 
+use Magento\Tax\Service\V1\TaxClassServiceInterface;
+
 class Form extends \Magento\Backend\Block\Widget\Form\Generic
 {
     /**
-     * @var \Magento\Tax\Model\Calculation\RateFactory
+     * @var \Magento\Tax\Model\Rate\Source
      */
-    protected $_rateFactory;
+    protected $rateSource;
 
     /**
      * @var \Magento\Framework\Data\Form\FormKey
      */
     protected $formKey;
 
+    /**
+     * @var \Magento\Tax\Service\V1\TaxRuleServiceInterface
+     */
+    protected $ruleService;
+
+    /**
+     * @var \Magento\Tax\Service\V1\TaxClassServiceInterface
+     */
+    protected $taxClassService;
+
+    /**
+     * @var \Magento\Tax\Model\TaxClass\Source\Customer
+     */
+    protected $customerTaxClassSource;
+
+    /**
+     * @var \Magento\Tax\Model\TaxClass\Source\Product
+     */
+    protected $productTaxClassSource;
+
+    /**
+     * @var \Magento\Tax\Helper\Data
+     */
+    protected $taxHelper;
+
     /**
      * @param \Magento\Backend\Block\Template\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\Tax\Model\Calculation\RateFactory $rateFactory
+     * @param \Magento\Tax\Model\Rate\Source $rateSource
+     * @param \Magento\Tax\Service\V1\TaxRuleServiceInterface $ruleService
+     * @param \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService
+     * @param \Magento\Tax\Model\TaxClass\Source\Customer $customerTaxClassSource
+     * @param \Magento\Tax\Model\TaxClass\Source\Product $productTaxClassSource
+     * @param \Magento\Tax\Helper\Data $taxHelper
      * @param array $data
      */
     public function __construct(
         \Magento\Backend\Block\Template\Context $context,
         \Magento\Framework\Registry $registry,
         \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\Tax\Model\Calculation\RateFactory $rateFactory,
+        \Magento\Tax\Model\Rate\Source $rateSource,
+        \Magento\Tax\Service\V1\TaxRuleServiceInterface $ruleService,
+        \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService,
+        \Magento\Tax\Model\TaxClass\Source\Customer $customerTaxClassSource,
+        \Magento\Tax\Model\TaxClass\Source\Product $productTaxClassSource,
+        \Magento\Tax\Helper\Data $taxHelper,
         array $data = array()
     ) {
-        $this->_rateFactory = $rateFactory;
+        $this->rateSource = $rateSource;
         $this->formKey = $context->getFormKey();
+        $this->ruleService = $ruleService;
+        $this->taxClassService = $taxClassService;
+        $this->customerTaxClassSource = $customerTaxClassSource;
+        $this->productTaxClassSource = $productTaxClassSource;
+        $this->taxHelper = $taxHelper;
         parent::__construct($context, $registry, $formFactory, $data);
     }
 
@@ -77,35 +119,47 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
      */
     protected function _prepareForm()
     {
-        $model = $this->_coreRegistry->registry('tax_rule');
+        $taxRuleId = $this->_coreRegistry->registry('tax_rule_id');
+        try {
+            $taxRule = $this->ruleService->getTaxRule($taxRuleId);
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            /** Tax rule not found */
+        }
         /** @var \Magento\Framework\Data\Form $form */
         $form = $this->_formFactory->create(
             array('data' => array('id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post'))
         );
+        $sessionFormValues = (array)$this->_coreRegistry->registry('tax_rule_form_data');
+        $taxRuleData = isset($taxRule) ? $this->extractTaxRuleData($taxRule) : [];
+        $formValues = array_merge($taxRuleData, $sessionFormValues);
 
         $fieldset = $form->addFieldset('base_fieldset', array('legend' => __('Tax Rule Information')));
 
-        $rates = $this->_rateFactory->create()->getCollection()->toOptionArray();
-
         $fieldset->addField(
             'code',
             'text',
-            array('name' => 'code', 'label' => __('Name'), 'class' => 'required-entry', 'required' => true)
+            array(
+                'name' => 'code',
+                'value' => isset($formValues['code']) ? $formValues['code'] : '',
+                'label' => __('Name'),
+                'class' => 'required-entry',
+                'required' => true
+            )
         );
 
         // Editable multiselect for customer tax class
-        $selectConfig = $this->getTaxClassSelectConfig(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER);
-        $selectedCustomerTax = $model->getId() ? $model
-            ->getCustomerTaxClasses() : $model
-            ->getCustomerTaxClassWithDefault();
+        $selectConfig = $this->getTaxClassSelectConfig(TaxClassServiceInterface::TYPE_CUSTOMER);
+        $selectedCustomerTax = isset($formValues['tax_customer_class'])
+            ? $formValues['tax_customer_class']
+            : $this->getDefaultCustomerTaxClass();
         $fieldset->addField(
-            $this->getTaxClassSelectHtmlId(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER),
+            'tax_customer_class',
             'editablemultiselect',
             array(
-                'name' => $this->getTaxClassSelectHtmlId(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER),
+                'name' => 'tax_customer_class',
                 'label' => __('Customer Tax Class'),
                 'class' => 'required-entry',
-                'values' => $model->getAllOptionsForClass(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER),
+                'values' => $this->customerTaxClassSource->getAllOptions(false),
                 'value' => $selectedCustomerTax,
                 'required' => true,
                 'select_config' => $selectConfig
@@ -115,18 +169,18 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
         );
 
         // Editable multiselect for product tax class
-        $selectConfig = $this->getTaxClassSelectConfig(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT);
-        $selectedProductTax = $model->getId() ? $model
-            ->getProductTaxClasses() : $model
-            ->getProductTaxClassWithDefault();
+        $selectConfig = $this->getTaxClassSelectConfig(TaxClassServiceInterface::TYPE_PRODUCT);
+        $selectedProductTax = isset($formValues['tax_product_class'])
+            ? $formValues['tax_product_class']
+            : $this->getDefaultProductTaxClass();
         $fieldset->addField(
-            $this->getTaxClassSelectHtmlId(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT),
+            'tax_product_class',
             'editablemultiselect',
             array(
-                'name' => $this->getTaxClassSelectHtmlId(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT),
+                'name' => 'tax_product_class',
                 'label' => __('Product Tax Class'),
                 'class' => 'required-entry',
-                'values' => $model->getAllOptionsForClass(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT),
+                'values' => $this->productTaxClassSource->getAllOptions(false),
                 'value' => $selectedProductTax,
                 'required' => true,
                 'select_config' => $selectConfig
@@ -142,8 +196,8 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'name' => 'tax_rate',
                 'label' => __('Tax Rate'),
                 'class' => 'required-entry',
-                'values' => $rates,
-                'value' => $model->getRates(),
+                'values' => $this->rateSource->toOptionArray(),
+                'value' => isset($formValues['tax_rate']) ? $formValues['tax_rate'] : [],
                 'required' => true,
                 'element_js_class' => 'TaxRateEditableMultiselect',
                 'select_config' => array('is_entity_editable' => true)
@@ -157,14 +211,14 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'name' => 'priority',
                 'label' => __('Priority'),
                 'class' => 'validate-not-negative-number',
-                'value' => (int)$model->getPriority(),
+                'value' => isset($formValues['priority']) ? $formValues['priority'] : 0,
                 'required' => true,
                 'note' => __('Tax rates at the same priority are added, others are compounded.')
             ),
             false,
             true
         );
-        
+
         $fieldset->addField(
             'calculate_subtotal',
             'checkbox',
@@ -172,7 +226,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'name'  => 'calculate_subtotal',
                 'label' => __('Calculate Off Subtotal Only'),
                 'onclick' => 'this.value = this.checked ? 1 : 0;',
-                'checked' => (int)$model->getCalculateSubtotal()
+                'checked' => isset($formValues['calculate_subtotal']) ? $formValues['calculate_subtotal'] : 0
             ),
             false,
             true
@@ -185,22 +239,21 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
                 'name' => 'position',
                 'label' => __('Sort Order'),
                 'class' => 'validate-not-negative-number',
-                'value' => (int)$model->getPosition(),
+                'value' => isset($formValues['position']) ? $formValues['position'] : 0,
                 'required' => true
             ),
             false,
             true
         );
 
-        if ($model->getId() > 0) {
+        if (isset($taxRule)) {
             $fieldset->addField(
                 'tax_calculation_rule_id',
                 'hidden',
-                array('name' => 'tax_calculation_rule_id', 'value' => $model->getId(), 'no_span' => true)
+                array('name' => 'tax_calculation_rule_id', 'value' => $taxRule->getId(), 'no_span' => true)
             );
         }
 
-        $form->addValues($model->getData());
         $form->setAction($this->getUrl('tax/rule/save'));
         $form->setUseContainer($this->getUseContainer());
         $this->setForm($form);
@@ -209,14 +262,43 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     }
 
     /**
-     * Retrieve HTML element ID for corresponding tax class selector
+     * Identify default customer tax class ID.
      *
-     * @param string $classType
-     * @return string
+     * @return int|null
      */
-    public function getTaxClassSelectHtmlId($classType)
+    public function getDefaultCustomerTaxClass()
     {
-        return 'tax_' . strtolower($classType) . '_class';
+        $configValue = $this->taxHelper->getDefaultCustomerTaxClass();
+        if (!empty($configValue)) {
+            return $configValue;
+        }
+        $taxClasses = $this->customerTaxClassSource->getAllOptions(false);
+        if (!empty($taxClasses)) {
+            $firstClass = array_shift($taxClasses);
+            return isset($firstClass['value']) ? $firstClass['value'] : null;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Identify default product tax class ID.
+     *
+     * @return int|null
+     */
+    public function getDefaultProductTaxClass()
+    {
+        $configValue = $this->taxHelper->getDefaultProductTaxClass();
+        if (!empty($configValue)) {
+            return $configValue;
+        }
+        $taxClasses = $this->productTaxClassSource->getAllOptions(false);
+        if (!empty($taxClasses)) {
+            $firstClass = array_shift($taxClasses);
+            return isset($firstClass['value']) ? $firstClass['value'] : null;
+        } else {
+            return null;
+        }
     }
 
     /**
@@ -232,7 +314,7 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
             'save_url' => $this->getUrl('tax/tax/ajaxSave/'),
             'delete_url' => $this->getUrl('tax/tax/ajaxDelete/'),
             'delete_confirm_message' => __('Do you really want to delete this tax class?'),
-            'target_select_id' => $this->getTaxClassSelectHtmlId($classType),
+            'target_select_id' => 'tax_' . strtolower($classType) . '_class',
             'add_button_caption' => __('Add New Tax Class'),
             'submit_data' => array('class_type' => $classType, 'form_key' => $this->formKey->getFormKey()),
             'entity_id_name' => 'class_id',
@@ -261,4 +343,24 @@ class Form extends \Magento\Backend\Block\Widget\Form\Generic
     {
         return $this->getUrl('tax/rate/ajaxSave/');
     }
+
+    /**
+     * Extract tax rule data in a format which is
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxRule $taxRule
+     * @return array
+     */
+    protected function extractTaxRuleData($taxRule)
+    {
+        $taxRuleData = [
+            'code' => $taxRule->getCode(),
+            'tax_customer_class' => $taxRule->getCustomerTaxClassIds(),
+            'tax_product_class' => $taxRule->getProductTaxClassIds(),
+            'tax_rate' => $taxRule->getTaxRateIds(),
+            'priority' => $taxRule->getPriority(),
+            'position' => $taxRule->getSortOrder(),
+            'calculate_subtotal' => $taxRule->getCalculateSubtotal()
+        ];
+        return $taxRuleData;
+    }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
index 09310a3b95d7e372a142d613bba9957306d55e3b..a9345cbfe80ee5706fe315ce07914ddb66d6f9de 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate.php
@@ -22,15 +22,13 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Tax\Controller\Adminhtml;
+
 /**
  * Adminhtml tax rate controller
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Tax\Controller\Adminhtml;
-
-use Magento\Framework\App\ResponseInterface;
-
 class Rate extends \Magento\Backend\App\Action
 {
     /**
@@ -39,153 +37,55 @@ class Rate extends \Magento\Backend\App\Action
     protected $_fileFactory;
 
     /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     * @var \Magento\Framework\Registry
      */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Framework\App\Response\Http\FileFactory $fileFactory
-    ) {
-        $this->_fileFactory = $fileFactory;
-        parent::__construct($context);
-    }
+    protected $_coreRegistry;
 
     /**
-     * Show Main Grid
-     *
-     * @return void
+     * @var \Magento\Tax\Service\V1\TaxRateServiceInterface
      */
-    public function indexAction()
-    {
-        $this->_title->add(__('Tax Zones and Rates'));
-
-        $this->_initAction()->_addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'));
-        $this->_view->renderLayout();
-    }
+    protected $_taxRateService;
 
     /**
-     * Show Add Form
-     *
-     * @return void
+     * @var \Magento\Tax\Service\V1\Data\TaxRateBuilder
      */
-    public function addAction()
-    {
-        $rateModel = $this->_objectManager->get('Magento\Tax\Model\Calculation\Rate')->load(null);
-
-        $this->_title->add(__('Tax Zones and Rates'));
-
-        $this->_title->add(__('New Tax Rate'));
-
-        $rateModel->setData($this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true));
-
-        if ($rateModel->getZipIsRange() && !$rateModel->hasTaxPostcode()) {
-            $rateModel->setTaxPostcode($rateModel->getZipFrom() . '-' . $rateModel->getZipTo());
-        }
-
-        $this->_initAction()->_addBreadcrumb(
-            __('Manage Tax Rates'),
-            __('Manage Tax Rates'),
-            $this->getUrl('tax/rate')
-        )->_addBreadcrumb(
-            __('New Tax Rate'),
-            __('New Tax Rate')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Tax\Block\Adminhtml\Rate\Toolbar\Save'
-            )->assign(
-                'header',
-                __('Add New Tax Rate')
-            )->assign(
-                'form',
-                $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\Form', 'tax_rate_form')
-            )
-        );
-        $this->_view->renderLayout();
-    }
+    protected $_taxRateBuilder;
 
     /**
-     * Save Rate and Data
-     *
-     * @return bool
+     * @var \Magento\Tax\Service\V1\Data\ZipRangeBuilder
      */
-    public function saveAction()
-    {
-        $ratePost = $this->getRequest()->getPost();
-        if ($ratePost) {
-            $rateId = $this->getRequest()->getParam('tax_calculation_rate_id');
-            if ($rateId) {
-                $rateModel = $this->_objectManager->get('Magento\Tax\Model\Calculation\Rate')->load($rateId);
-                if (!$rateModel->getId()) {
-                    unset($ratePost['tax_calculation_rate_id']);
-                }
-            }
-
-            $rateModel = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rate')->setData($ratePost);
-
-            try {
-                $rateModel->save();
-
-                $this->messageManager->addSuccess(__('The tax rate has been saved.'));
-                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-                return true;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($ratePost);
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
+    protected $_zipRangeBuilder;
 
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            return;
-        }
-        $this->getResponse()->setRedirect($this->getUrl('tax/rate'));
-    }
+    /**
+     * @var \Magento\Tax\Service\V1\Data\TaxRateTitleBuilder
+     */
+    protected $_taxRateTitleBuilder;
 
     /**
-     * Save Tax Rate via AJAX
-     *
-     * @return void
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileFactory
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService
+     * @param \Magento\Tax\Service\V1\Data\TaxRateBuilder $taxRateBuilder
+     * @param \Magento\Tax\Service\V1\Data\ZipRangeBuilder $zipRangeBuilder
+     * @param \Magento\Tax\Service\V1\Data\TaxRateTitleBuilder $taxRateTitleBuilder
      */
-    public function ajaxSaveAction()
-    {
-        $responseContent = '';
-        try {
-            $rateData = $this->_processRateData($this->getRequest()->getPost());
-            $rate = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rate')->setData($rateData)->save();
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'success' => true,
-                    'error_message' => '',
-                    'tax_calculation_rate_id' => $rate->getId(),
-                    'code' => $rate->getCode()
-                )
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'success' => false,
-                    'error_message' => $e->getMessage(),
-                    'tax_calculation_rate_id' => '',
-                    'code' => ''
-                )
-            );
-        } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'success' => false,
-                    'error_message' => __('Something went wrong saving this rate.'),
-                    'tax_calculation_rate_id' => '',
-                    'code' => ''
-                )
-            );
-        }
-        $this->getResponse()->representJson($responseContent);
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileFactory,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Tax\Service\V1\TaxRateServiceInterface $taxRateService,
+        \Magento\Tax\Service\V1\Data\TaxRateBuilder $taxRateBuilder,
+        \Magento\Tax\Service\V1\Data\ZipRangeBuilder $zipRangeBuilder,
+        \Magento\Tax\Service\V1\Data\TaxRateTitleBuilder $taxRateTitleBuilder
+    ) {
+        $this->_fileFactory = $fileFactory;
+        $this->_coreRegistry = $coreRegistry;
+        $this->_taxRateService = $taxRateService;
+        $this->_taxRateBuilder = $taxRateBuilder;
+        $this->_zipRangeBuilder = $zipRangeBuilder;
+        $this->_taxRateTitleBuilder = $taxRateTitleBuilder;
+        parent::__construct($context);
     }
 
     /**
@@ -207,147 +107,6 @@ class Rate extends \Magento\Backend\App\Action
         return $result;
     }
 
-    /**
-     * Show Edit Form
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Tax Zones and Rates'));
-
-        $rateId = (int)$this->getRequest()->getParam('rate');
-        $rateModel = $this->_objectManager->get('Magento\Tax\Model\Calculation\Rate')->load($rateId);
-        if (!$rateModel->getId()) {
-            $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-            return;
-        }
-
-        if ($rateModel->getZipIsRange() && !$rateModel->hasTaxPostcode()) {
-            $rateModel->setTaxPostcode($rateModel->getZipFrom() . '-' . $rateModel->getZipTo());
-        }
-
-        $this->_title->add(sprintf("%s", $rateModel->getCode()));
-
-        $this->_initAction()->_addBreadcrumb(
-            __('Manage Tax Rates'),
-            __('Manage Tax Rates'),
-            $this->getUrl('tax/rate')
-        )->_addBreadcrumb(
-            __('Edit Tax Rate'),
-            __('Edit Tax Rate')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock(
-                'Magento\Tax\Block\Adminhtml\Rate\Toolbar\Save'
-            )->assign(
-                'header',
-                __('Edit Tax Rate')
-            )->assign(
-                'form',
-                $this->_view->getLayout()->createBlock(
-                    'Magento\Tax\Block\Adminhtml\Rate\Form',
-                    'tax_rate_form'
-                )->setShowLegend(
-                    true
-                )
-            )
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Delete Rate and Data
-     *
-     * @return bool
-     */
-    public function deleteAction()
-    {
-        if ($rateId = $this->getRequest()->getParam('rate')) {
-            $rateModel = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rate')->load($rateId);
-            if ($rateModel->getId()) {
-                try {
-                    $rateModel->delete();
-
-                    $this->messageManager->addSuccess(__('The tax rate has been deleted.'));
-                    $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-                    return true;
-                } catch (\Magento\Framework\Model\Exception $e) {
-                    $this->messageManager->addError($e->getMessage());
-                } catch (\Exception $e) {
-                    $this->messageManager->addError(__('Something went wrong deleting this rate.'));
-                }
-                if ($referer = $this->getRequest()->getServer('HTTP_REFERER')) {
-                    $this->getResponse()->setRedirect($referer);
-                } else {
-                    $this->getResponse()->setRedirect($this->getUrl("*/*/"));
-                }
-            } else {
-                $this->messageManager->addError(
-                    __('Something went wrong deleting this rate because of an incorrect rate ID.')
-                );
-                $this->getResponse()->setRedirect($this->getUrl('tax/*/'));
-            }
-        }
-    }
-
-    /**
-     * Delete Tax Rate via AJAX
-     *
-     * @return void
-     */
-    public function ajaxDeleteAction()
-    {
-
-        $responseContent = '';
-        $rateId = (int)$this->getRequest()->getParam('tax_calculation_rate_id');
-        try {
-            $rate = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rate')->load($rateId);
-            $rate->delete();
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => true, 'error_message' => '')
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => false, 'error_message' => $e->getMessage())
-            );
-        } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => false, 'error_message' => __('An error occurred while deleting this tax rate.'))
-            );
-        }
-        $this->getResponse()->representJson($responseContent);
-    }
-
-    /**
-     * Export rates grid to CSV format
-     *
-     * @return ResponseInterface
-     */
-    public function exportCsvAction()
-    {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
-        return $this->_fileFactory->create('rates.csv', $content->getCsvFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
-    /**
-     * Export rates grid to XML format
-     *
-     * @return ResponseInterface
-     */
-    public function exportXmlAction()
-    {
-        $this->_view->loadLayout(false);
-        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
-        return $this->_fileFactory->create('rates.xml', $content->getExcelFile(), \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
     /**
      * Initialize action
      *
@@ -368,128 +127,6 @@ class Rate extends \Magento\Backend\App\Action
         return $this;
     }
 
-    /**
-     * Import and export Page
-     *
-     * @return void
-     */
-    public function importExportAction()
-    {
-        $this->_title->add(__('Tax Zones and Rates'));
-
-        $this->_title->add(__('Import and Export Tax Rates'));
-
-        $this->_view->loadLayout();
-        $this->_setActiveMenu(
-            'Magento_Tax::system_convert_tax'
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\ImportExportHeader')
-        )->_addContent(
-            $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\ImportExport')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * import action from import/export tax
-     *
-     * @return void
-     */
-    public function importPostAction()
-    {
-        if ($this->getRequest()->isPost() && !empty($_FILES['import_rates_file']['tmp_name'])) {
-            try {
-                /** @var $importHandler \Magento\Tax\Model\Rate\CsvImportHandler */
-                $importHandler = $this->_objectManager->create('Magento\Tax\Model\Rate\CsvImportHandler');
-                $importHandler->importFromCsvFile($this->getRequest()->getFiles('import_rates_file'));
-
-                $this->messageManager->addSuccess(__('The tax rate has been imported.'));
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Invalid file upload attempt'));
-            }
-        } else {
-            $this->messageManager->addError(__('Invalid file upload attempt'));
-        }
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
-    /**
-     * export action from import/export tax
-     *
-     * @return ResponseInterface
-     */
-    public function exportPostAction()
-    {
-        /** start csv content and set template */
-        $headers = new \Magento\Framework\Object(
-            array(
-                'code' => __('Code'),
-                'country_name' => __('Country'),
-                'region_name' => __('State'),
-                'tax_postcode' => __('Zip/Post Code'),
-                'rate' => __('Rate'),
-                'zip_is_range' => __('Zip/Post is Range'),
-                'zip_from' => __('Range From'),
-                'zip_to' => __('Range To')
-            )
-        );
-        $template = '"{{code}}","{{country_name}}","{{region_name}}","{{tax_postcode}}","{{rate}}"' .
-            ',"{{zip_is_range}}","{{zip_from}}","{{zip_to}}"';
-        $content = $headers->toString($template);
-
-        $storeTaxTitleTemplate = array();
-        $taxCalculationRateTitleDict = array();
-
-        foreach ($this->_objectManager->create(
-            'Magento\Store\Model\Store'
-        )->getCollection()->setLoadDefault(
-            false
-        ) as $store) {
-            $storeTitle = 'title_' . $store->getId();
-            $content .= ',"' . $store->getCode() . '"';
-            $template .= ',"{{' . $storeTitle . '}}"';
-            $storeTaxTitleTemplate[$storeTitle] = null;
-        }
-        unset($store);
-
-        $content .= "\n";
-
-        foreach ($this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rate\Title'
-        )->getCollection() as $title) {
-            $rateId = $title->getTaxCalculationRateId();
-
-            if (!array_key_exists($rateId, $taxCalculationRateTitleDict)) {
-                $taxCalculationRateTitleDict[$rateId] = $storeTaxTitleTemplate;
-            }
-
-            $taxCalculationRateTitleDict[$rateId]['title_' . $title->getStoreId()] = $title->getValue();
-        }
-        unset($title);
-
-        $collection = $this->_objectManager->create(
-            'Magento\Tax\Model\Resource\Calculation\Rate\Collection'
-        )->joinCountryTable()->joinRegionTable();
-
-        while ($rate = $collection->fetchItem()) {
-            if ($rate->getTaxRegionId() == 0) {
-                $rate->setRegionName('*');
-            }
-
-            if (array_key_exists($rate->getId(), $taxCalculationRateTitleDict)) {
-                $rate->addData($taxCalculationRateTitleDict[$rate->getId()]);
-            } else {
-                $rate->addData($storeTaxTitleTemplate);
-            }
-
-            $content .= $rate->toString($template) . "\n";
-        }
-        $this->_view->loadLayout();
-        return $this->_fileFactory->create('tax_rates.csv', $content, \Magento\Framework\App\Filesystem::VAR_DIR);
-    }
-
     /**
      * @return bool
      */
@@ -518,4 +155,52 @@ class Rate extends \Magento\Backend\App\Action
                 break;
         }
     }
+
+    /**
+     * Populate a tax rate data object
+     *
+     * @param array $formData
+     * @return \Magento\Tax\Service\V1\Data\TaxRate
+     */
+    protected function populateTaxRateData($formData)
+    {
+        $this->_taxRateBuilder->setId($this->extractFormData($formData, 'tax_calculation_rate_id'))
+            ->setCountryId($this->extractFormData($formData, 'tax_country_id'))
+            ->setRegionId($this->extractFormData($formData, 'tax_region_id'))
+            ->setPostcode($this->extractFormData($formData, 'tax_postcode'))
+            ->setCode($this->extractFormData($formData, 'code'))
+            ->setPercentageRate($this->extractFormData($formData, 'rate'));
+
+        if (isset($formData['zip_is_range']) && $formData['zip_is_range']) {
+            $this->_zipRangeBuilder->setFrom($this->extractFormData($formData, 'zip_from'))
+                ->setTo($this->extractFormData($formData, 'zip_to'));
+            $zipRange = $this->_zipRangeBuilder->create();
+            $this->_taxRateBuilder->setZipRange($zipRange);
+        }
+
+        if (isset($formData['title'])) {
+            $titles = [];
+            foreach ($formData['title'] as $storeId => $value) {
+                $titles[] = $this->_taxRateTitleBuilder->setStoreId($storeId)->setValue($value)->create();
+            }
+            $this->_taxRateBuilder->setTitles($titles);
+        }
+
+        return $this->_taxRateBuilder->create();
+    }
+
+    /**
+     * Determines if an array value is set in the form data array and returns it.
+     *
+     * @param array $formData the form to get data from
+     * @param string $fieldName the key
+     * @return null|string
+     */
+    protected function extractFormData($formData, $fieldName)
+    {
+        if (isset($formData[$fieldName])) {
+            return $formData[$fieldName];
+        }
+        return null;
+    }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Add.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..5126e1ebc6bd088a1e4b3758dd28fdf9caa52912
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Add.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use Magento\Tax\Controller\RegistryConstants;
+
+class Add extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Show Add Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Zones and Rates'));
+
+        $this->_title->add(__('New Tax Rate'));
+
+        $this->_coreRegistry->register(
+            RegistryConstants::CURRENT_TAX_RATE_FORM_DATA,
+            $this->_objectManager->get('Magento\Backend\Model\Session')->getFormData(true)
+        );
+
+        $this->_initAction()->_addBreadcrumb(
+            __('Manage Tax Rates'),
+            __('Manage Tax Rates'),
+            $this->getUrl('tax/rate')
+        )->_addBreadcrumb(
+            __('New Tax Rate'),
+            __('New Tax Rate')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Tax\Block\Adminhtml\Rate\Toolbar\Save'
+            )->assign(
+                'header',
+                __('Add New Tax Rate')
+            )->assign(
+                'form',
+                $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\Form', 'tax_rate_form')
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..49fbf8770542a0800acc22afc88357220c966f77
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxDelete.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+class AjaxDelete extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Delete Tax Rate via AJAX
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $rateId = (int)$this->getRequest()->getParam('tax_calculation_rate_id');
+        try {
+            $this->_taxRateService->deleteTaxRate($rateId);
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => true, 'error_message' => '')
+            );
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => false, 'error_message' => $e->getMessage())
+            );
+        } catch (\Exception $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => false, 'error_message' => __('An error occurred while deleting this tax rate.'))
+            );
+        }
+        $this->getResponse()->representJson($responseContent);
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd6fd75051afa8a0cc5fbad07ce7d3de0b70d506
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/AjaxSave.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+class AjaxSave extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Save Tax Rate via AJAX
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $responseContent = '';
+        try {
+            $rateData = $this->_processRateData($this->getRequest()->getPost());
+            $taxRate = $this->populateTaxRateData($rateData);
+            $taxRateId = $taxRate->getId();
+            if ($taxRateId) {
+                $this->_taxRateService->updateTaxRate($taxRate);
+            } else {
+                $taxRate = $this->_taxRateService->createTaxRate($taxRate);
+                $taxRateId = $taxRate->getId();
+            }
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'success' => true,
+                    'error_message' => '',
+                    'tax_calculation_rate_id' => $taxRate->getId(),
+                    'code' => $taxRate->getCode()
+                )
+            );
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'success' => false,
+                    'error_message' => $e->getMessage(),
+                    'tax_calculation_rate_id' => '',
+                    'code' => ''
+                )
+            );
+        } catch (\Exception $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'success' => false,
+                    'error_message' => __('Something went wrong saving this rate.'),
+                    'tax_calculation_rate_id' => '',
+                    'code' => ''
+                )
+            );
+        }
+        $this->getResponse()->representJson($responseContent);
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..065c2cc53be91f175596665c7e4d939d5f18891c
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Delete.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class Delete extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Delete Rate and Data
+     *
+     * @return bool
+     */
+    public function execute()
+    {
+        if ($rateId = $this->getRequest()->getParam('rate')) {
+            try {
+                $this->_taxRateService->deleteTaxRate($rateId);
+
+                $this->messageManager->addSuccess(__('The tax rate has been deleted.'));
+                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
+                return true;
+            } catch (NoSuchEntityException $e) {
+                $this->messageManager->addError(
+                    __('Something went wrong deleting this rate because of an incorrect rate ID.')
+                );
+                $this->getResponse()->setRedirect($this->getUrl('tax/*/'));
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong deleting this rate.'));
+            }
+
+            if ($referer = $this->getRequest()->getServer('HTTP_REFERER')) {
+                $this->getResponse()->setRedirect($referer);
+            } else {
+                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..3cbc1fa50657539a486bc5d368fa9baa79b3c9f1
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Edit.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Tax\Controller\RegistryConstants;
+
+class Edit extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Show Edit Form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Zones and Rates'));
+
+        $rateId = (int)$this->getRequest()->getParam('rate');
+        $this->_coreRegistry->register(RegistryConstants::CURRENT_TAX_RATE_ID, $rateId);
+        try {
+            $taxRateDataObject = $this->_taxRateService->getTaxRate($rateId);
+        } catch (NoSuchEntityException $e) {
+            $this->getResponse()->setRedirect($this->getUrl("*/*/"));
+            return;
+        }
+
+        $this->_title->add(sprintf("%s", $taxRateDataObject->getCode()));
+
+        $this->_initAction()->_addBreadcrumb(
+            __('Manage Tax Rates'),
+            __('Manage Tax Rates'),
+            $this->getUrl('tax/rate')
+        )->_addBreadcrumb(
+            __('Edit Tax Rate'),
+            __('Edit Tax Rate')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock(
+                'Magento\Tax\Block\Adminhtml\Rate\Toolbar\Save'
+            )->assign(
+                'header',
+                __('Edit Tax Rate')
+            )->assign(
+                'form',
+                $this->_view->getLayout()->createBlock(
+                    'Magento\Tax\Block\Adminhtml\Rate\Form',
+                    'tax_rate_form'
+                )->setShowLegend(
+                    true
+                )
+            )
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportCsv.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportCsv.php
new file mode 100644
index 0000000000000000000000000000000000000000..2edb90151f59965000506a862648f56939c00b46
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportCsv.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportCsv extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Export rates grid to CSV format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            'rates.csv',
+            $content->getCsvFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportPost.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..2c0c0363383936d75924cf48381b0e0d673a61dd
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportPost.php
@@ -0,0 +1,105 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportPost extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * export action from import/export tax
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        /** start csv content and set template */
+        $headers = new \Magento\Framework\Object(
+            array(
+                'code' => __('Code'),
+                'country_name' => __('Country'),
+                'region_name' => __('State'),
+                'tax_postcode' => __('Zip/Post Code'),
+                'rate' => __('Rate'),
+                'zip_is_range' => __('Zip/Post is Range'),
+                'zip_from' => __('Range From'),
+                'zip_to' => __('Range To')
+            )
+        );
+        $template = '"{{code}}","{{country_name}}","{{region_name}}","{{tax_postcode}}","{{rate}}"' .
+            ',"{{zip_is_range}}","{{zip_from}}","{{zip_to}}"';
+        $content = $headers->toString($template);
+
+        $storeTaxTitleTemplate = array();
+        $taxCalculationRateTitleDict = array();
+
+        foreach ($this->_objectManager->create(
+            'Magento\Store\Model\Store'
+        )->getCollection()->setLoadDefault(
+            false
+        ) as $store) {
+            $storeTitle = 'title_' . $store->getId();
+            $content .= ',"' . $store->getCode() . '"';
+            $template .= ',"{{' . $storeTitle . '}}"';
+            $storeTaxTitleTemplate[$storeTitle] = null;
+        }
+        unset($store);
+
+        $content .= "\n";
+
+        foreach ($this->_objectManager->create(
+            'Magento\Tax\Model\Calculation\Rate\Title'
+        )->getCollection() as $title) {
+            $rateId = $title->getTaxCalculationRateId();
+
+            if (!array_key_exists($rateId, $taxCalculationRateTitleDict)) {
+                $taxCalculationRateTitleDict[$rateId] = $storeTaxTitleTemplate;
+            }
+
+            $taxCalculationRateTitleDict[$rateId]['title_' . $title->getStoreId()] = $title->getValue();
+        }
+        unset($title);
+
+        $collection = $this->_objectManager->create(
+            'Magento\Tax\Model\Resource\Calculation\Rate\Collection'
+        )->joinCountryTable()->joinRegionTable();
+
+        while ($rate = $collection->fetchItem()) {
+            if ($rate->getTaxRegionId() == 0) {
+                $rate->setRegionName('*');
+            }
+
+            if (array_key_exists($rate->getId(), $taxCalculationRateTitleDict)) {
+                $rate->addData($taxCalculationRateTitleDict[$rate->getId()]);
+            } else {
+                $rate->addData($storeTaxTitleTemplate);
+            }
+
+            $content .= $rate->toString($template) . "\n";
+        }
+        $this->_view->loadLayout();
+        return $this->_fileFactory->create('tax_rates.csv', $content, \Magento\Framework\App\Filesystem::VAR_DIR);
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportXml.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportXml.php
new file mode 100644
index 0000000000000000000000000000000000000000..ca829de220a63a81dce170668ff85958f9b17042
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ExportXml.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class ExportXml extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Export rates grid to XML format
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $content = $this->_view->getLayout()->getChildBlock('adminhtml.tax.rate.grid', 'grid.export');
+        return $this->_fileFactory->create(
+            'rates.xml',
+            $content->getExcelFile(),
+            \Magento\Framework\App\Filesystem::VAR_DIR
+        );
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportExport.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportExport.php
new file mode 100644
index 0000000000000000000000000000000000000000..4165a32467d8a936dbd13dc40dae1b168eb16bf6
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportExport.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+class ImportExport extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Import and export Page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Zones and Rates'));
+
+        $this->_title->add(__('Import and Export Tax Rates'));
+
+        $this->_view->loadLayout();
+        $this->_setActiveMenu(
+            'Magento_Tax::system_convert_tax'
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\ImportExportHeader')
+        )->_addContent(
+            $this->_view->getLayout()->createBlock('Magento\Tax\Block\Adminhtml\Rate\ImportExport')
+        );
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportPost.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..659d90992a7e52f377c4e7d3b25510b4d708a63d
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/ImportPost.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+class ImportPost extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * import action from import/export tax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if ($this->getRequest()->isPost() && !empty($_FILES['import_rates_file']['tmp_name'])) {
+            try {
+                /** @var $importHandler \Magento\Tax\Model\Rate\CsvImportHandler */
+                $importHandler = $this->_objectManager->create('Magento\Tax\Model\Rate\CsvImportHandler');
+                $importHandler->importFromCsvFile($this->getRequest()->getFiles('import_rates_file'));
+
+                $this->messageManager->addSuccess(__('The tax rate has been imported.'));
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Invalid file upload attempt'));
+            }
+        } else {
+            $this->messageManager->addError(__('Invalid file upload attempt'));
+        }
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ed31dbe06cad6954c3111dc6a54dac8dfc0e983
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+class Index extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Show Main Grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Zones and Rates'));
+
+        $this->_initAction()->_addBreadcrumb(__('Manage Tax Rates'), __('Manage Tax Rates'));
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..edca03a2b3623971c60da34cf8e2ede5712cf8c4
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rate/Save.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rate;
+
+use Magento\Framework\Exception\NoSuchEntityException;
+
+class Save extends \Magento\Tax\Controller\Adminhtml\Rate
+{
+    /**
+     * Save Rate and Data
+     *
+     * @return bool
+     */
+    public function execute()
+    {
+        $ratePost = $this->getRequest()->getPost();
+        if ($ratePost) {
+            $rateId = $this->getRequest()->getParam('tax_calculation_rate_id');
+            if ($rateId) {
+                try {
+                    $this->_taxRateService->getTaxRate($rateId);
+                } catch (NoSuchEntityException $e) {
+                    unset($ratePost['tax_calculation_rate_id']);
+                }
+            }
+
+            try {
+                $taxData = $this->populateTaxRateData($ratePost);
+                if (isset($ratePost['tax_calculation_rate_id'])) {
+                    $this->_taxRateService->updateTaxRate($taxData);
+                } else {
+                    $this->_taxRateService->createTaxRate($taxData);
+                }
+
+                $this->messageManager->addSuccess(__('The tax rate has been saved.'));
+                $this->getResponse()->setRedirect($this->getUrl("*/*/"));
+                return true;
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($ratePost);
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+            return;
+        }
+        $this->getResponse()->setRedirect($this->getUrl('tax/rate'));
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
index 9de72cd297dea671dc07c8b121d33542990c1b74..d80ce589b518c031ef6eeda6e65bb06a72dbbcc8 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule.php
@@ -40,147 +40,30 @@ class Rule extends \Magento\Backend\App\Action
      */
     protected $_coreRegistry = null;
 
+    /** @var \Magento\Tax\Service\V1\TaxRuleServiceInterface */
+    protected $ruleService;
+
+    /** @var \Magento\Tax\Service\V1\Data\TaxRuleBuilder */
+    protected $ruleBuilder;
+
     /**
      * @param \Magento\Backend\App\Action\Context $context
      * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Tax\Service\V1\TaxRuleServiceInterface $ruleService
+     * @param \Magento\Tax\Service\V1\Data\TaxRuleBuilder $ruleBuilder
      */
-    public function __construct(\Magento\Backend\App\Action\Context $context, \Magento\Framework\Registry $coreRegistry)
-    {
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Tax\Service\V1\TaxRuleServiceInterface $ruleService,
+        \Magento\Tax\Service\V1\Data\TaxRuleBuilder $ruleBuilder
+    ) {
         $this->_coreRegistry = $coreRegistry;
+        $this->ruleService = $ruleService;
+        $this->ruleBuilder = $ruleBuilder;
         parent::__construct($context);
     }
 
-    /**
-     * Index action
-     *
-     * @return $this
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Tax Rules'));
-        $this->_initAction();
-        $this->_view->renderLayout();
-
-        return $this;
-    }
-
-    /**
-     * Redirects to edit action
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Tax Rules'));
-
-        $taxRuleId = $this->getRequest()->getParam('rule');
-        $ruleModel = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rule');
-        if ($taxRuleId) {
-            $ruleModel->load($taxRuleId);
-            if (!$ruleModel->getId()) {
-                $this->_objectManager->get('Magento\Backend\Model\Session')->unsRuleData();
-                $this->messageManager->addError(__('This rule no longer exists.'));
-                $this->_redirect('tax/*/');
-                return;
-            }
-        }
-
-        $data = $this->_objectManager->get('Magento\Backend\Model\Session')->getRuleData(true);
-        if (!empty($data)) {
-            $ruleModel->setData($data);
-        }
-
-        $this->_title->add($ruleModel->getId() ? sprintf("%s", $ruleModel->getCode()) : __('New Tax Rule'));
-
-        $this->_coreRegistry->register('tax_rule', $ruleModel);
-
-        $this->_initAction()->_addBreadcrumb(
-            $taxRuleId ? __('Edit Rule') : __('New Rule'),
-            $taxRuleId ? __('Edit Rule') : __('New Rule')
-        );
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $postData = $this->getRequest()->getPost();
-        if ($postData) {
-
-            $ruleModel = $this->_objectManager->get('Magento\Tax\Model\Calculation\Rule');
-            $ruleModel->setData($postData);
-            $ruleModel->setCalculateSubtotal($this->getRequest()->getParam('calculate_subtotal', 0));
-
-            try {
-                $ruleModel->save();
-
-                $this->messageManager->addSuccess(__('The tax rule has been saved.'));
-
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('tax/*/edit', array('rule' => $ruleModel->getId()));
-                    return;
-                }
-
-                $this->_redirect('tax/*/');
-                return;
-            } catch (\Magento\Framework\Model\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            } catch (\Exception $e) {
-                $this->messageManager->addError(__('Something went wrong saving this tax rule.'));
-            }
-
-            $this->_objectManager->get('Magento\Backend\Model\Session')->setRuleData($postData);
-            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-            return;
-        }
-        $this->getResponse()->setRedirect($this->getUrl('tax/rule'));
-    }
-
-    /**
-     * Delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $ruleId = (int)$this->getRequest()->getParam('rule');
-        $ruleModel = $this->_objectManager->get('Magento\Tax\Model\Calculation\Rule')->load($ruleId);
-        if (!$ruleModel->getId()) {
-            $this->messageManager->addError(__('This rule no longer exists'));
-            $this->_redirect('tax/*/');
-            return;
-        }
-
-        try {
-            $ruleModel->delete();
-
-            $this->messageManager->addSuccess(__('The tax rule has been deleted.'));
-            $this->_redirect('tax/*/');
-
-            return;
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('Something went wrong deleting this tax rule.'));
-        }
-
-        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
-    }
-
     /**
      * Initialize action
      *
@@ -210,4 +93,39 @@ class Rule extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Tax::manage_tax');
     }
+
+    /**
+     * Initialize tax rule service object with form data.
+     *
+     * @param array $postData
+     * @return \Magento\Tax\Service\V1\Data\TaxRule
+     */
+    protected function populateTaxRule($postData)
+    {
+        if (isset($postData['tax_calculation_rule_id'])) {
+            $this->ruleBuilder->setId($postData['tax_calculation_rule_id']);
+        }
+        if (isset($postData['code'])) {
+            $this->ruleBuilder->setCode($postData['code']);
+        }
+        if (isset($postData['tax_rate'])) {
+            $this->ruleBuilder->setTaxRateIds($postData['tax_rate']);
+        }
+        if (isset($postData['tax_customer_class'])) {
+            $this->ruleBuilder->setCustomerTaxClassIds($postData['tax_customer_class']);
+        }
+        if (isset($postData['tax_product_class'])) {
+            $this->ruleBuilder->setProductTaxClassIds($postData['tax_product_class']);
+        }
+        if (isset($postData['priority'])) {
+            $this->ruleBuilder->setPriority($postData['priority']);
+        }
+        if (isset($postData['calculate_subtotal'])) {
+            $this->ruleBuilder->setCalculateSubtotal($postData['calculate_subtotal']);
+        }
+        if (isset($postData['position'])) {
+            $this->ruleBuilder->setSortOrder($postData['position']);
+        }
+        return $this->ruleBuilder->create();
+    }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f8d324e028271470471339130530d67acd620ea
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Delete.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rule;
+
+use \Magento\Backend\App\Action;
+
+class Delete extends \Magento\Tax\Controller\Adminhtml\Rule
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $ruleId = (int)$this->getRequest()->getParam('rule');
+        try {
+            $this->ruleService->deleteTaxRule($ruleId);
+            $this->messageManager->addSuccess(__('The tax rule has been deleted.'));
+            $this->_redirect('tax/*/');
+            return;
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            $this->messageManager->addError(__('This rule no longer exists.'));
+            $this->_redirect('tax/*/');
+            return;
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('Something went wrong deleting this tax rule.'));
+        }
+
+        $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..abe0afd1dee3a6d84e3a9131dfaca6cced6c321a
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Edit.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rule;
+
+use \Magento\Backend\App\Action;
+
+class Edit extends \Magento\Tax\Controller\Adminhtml\Rule
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Rules'));
+
+        $taxRuleId = $this->getRequest()->getParam('rule');
+        $this->_coreRegistry->register('tax_rule_id', $taxRuleId);
+        /** @var \Magento\Backend\Model\Session $backendSession */
+        $backendSession = $this->_objectManager->get('Magento\Backend\Model\Session');
+        if ($taxRuleId) {
+            try {
+                $taxRule = $this->ruleService->getTaxRule($taxRuleId);
+                $pageTitle = sprintf("%s", $taxRule->getCode());
+            } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+                $backendSession->unsRuleData();
+                $this->messageManager->addError(__('This rule no longer exists.'));
+                $this->_redirect('tax/*/');
+                return;
+            }
+        } else {
+            $pageTitle = __('New Tax Rule');
+        }
+        $this->_title->add($pageTitle);
+        $data = $backendSession->getRuleData(true);
+        if (!empty($data)) {
+            $this->_coreRegistry->register('tax_rule_form_data', $data);
+        }
+        $breadcrumb = $taxRuleId ? __('Edit Rule') : __('New Rule');
+        $this->_initAction()->_addBreadcrumb($breadcrumb, $breadcrumb);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..5a9e2449333005f62d0155ae10fbe4a3ff90b9f0
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rule;
+
+use \Magento\Backend\App\Action;
+
+class Index extends \Magento\Tax\Controller\Adminhtml\Rule
+{
+    /**
+     * @return $this
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Tax Rules'));
+        $this->_initAction();
+        $this->_view->renderLayout();
+
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..70f57a06d1af3a4b8ae8a36b3e59d34a83482193
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rule;
+
+use \Magento\Backend\App\Action;
+
+class NewAction extends \Magento\Tax\Controller\Adminhtml\Rule
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ad9f0d0e169219d0232c33620a2ac8fb58fc635
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Rule/Save.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Rule;
+
+use \Magento\Backend\App\Action;
+
+class Save extends \Magento\Tax\Controller\Adminhtml\Rule
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $postData = $this->getRequest()->getPost();
+        if ($postData) {
+            $postData['calculate_subtotal'] = $this->getRequest()->getParam('calculate_subtotal', 0);
+            $taxRule = $this->populateTaxRule($postData);
+            try {
+                if ($taxRule->getId()) {
+                    $this->ruleService->updateTaxRule($taxRule);
+                } else {
+                    $taxRule = $this->ruleService->createTaxRule($taxRule);
+                }
+
+                $this->messageManager->addSuccess(__('The tax rule has been saved.'));
+
+                if ($this->getRequest()->getParam('back')) {
+                    $this->_redirect('tax/*/edit', array('rule' => $taxRule->getId()));
+                    return;
+                }
+
+                $this->_redirect('tax/*/');
+                return;
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                $this->messageManager->addError($e->getMessage());
+            } catch (\Exception $e) {
+                $this->messageManager->addError(__('Something went wrong saving this tax rule.'));
+            }
+
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setRuleData($postData);
+            $this->getResponse()->setRedirect($this->_redirect->getRedirectUrl($this->getUrl('*')));
+            return;
+        }
+        $this->getResponse()->setRedirect($this->getUrl('tax/rule'));
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax.php
index 3bd85afc9548593ff0d0ac8004f2e65319827756..2ebc4fa90dc52434924cf0db0245fe3689243ce7 100644
--- a/app/code/Magento/Tax/Controller/Adminhtml/Tax.php
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax.php
@@ -22,111 +22,40 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
+namespace Magento\Tax\Controller\Adminhtml;
+
+use Magento\Framework\Exception\InputException;
+
 /**
  * Adminhtml common tax class controller
  *
  * @author      Magento Core Team <core@magentocommerce.com>
  */
-namespace Magento\Tax\Controller\Adminhtml;
-
 class Tax extends \Magento\Backend\App\Action
 {
     /**
-     * Save Tax Class via AJAX
-     *
-     * @return void
+     * @var \Magento\Tax\Service\V1\TaxClassServiceInterface
      */
-    public function ajaxSaveAction()
-    {
-        $responseContent = '';
-        try {
-            $classData = array(
-                'class_id' => (int)$this->getRequest()->getPost('class_id') ?: null, // keep null for new tax classes
-                'class_type' => $this->_processClassType((string)$this->getRequest()->getPost('class_type')),
-                'class_name' => $this->_processClassName((string)$this->getRequest()->getPost('class_name'))
-            );
-            $class = $this->_objectManager->create('Magento\Tax\Model\ClassModel')->setData($classData)->save();
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'success' => true,
-                    'error_message' => '',
-                    'class_id' => $class->getId(),
-                    'class_name' => $class->getClassName()
-                )
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => false, 'error_message' => $e->getMessage(), 'class_id' => '', 'class_name' => '')
-            );
-        } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array(
-                    'success' => false,
-                    'error_message' => __('Something went wrong saving this tax class.'),
-                    'class_id' => '',
-                    'class_name' => ''
-                )
-            );
-        }
-        $this->getResponse()->representJson($responseContent);
-    }
+    protected $taxClassService;
 
     /**
-     * Delete Tax Class via AJAX
-     *
-     * @return void
+     * @var \Magento\Tax\Service\V1\Data\TaxClassBuilder
      */
-    public function ajaxDeleteAction()
-    {
-        $classId = (int)$this->getRequest()->getParam('class_id');
-        try {
-            /** @var $classModel \Magento\Tax\Model\ClassModel */
-            $classModel = $this->_objectManager->create('Magento\Tax\Model\ClassModel')->load($classId);
-            $classModel->delete();
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => true, 'error_message' => '')
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => false, 'error_message' => $e->getMessage())
-            );
-        } catch (\Exception $e) {
-            $responseContent = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonEncode(
-                array('success' => false, 'error_message' => __('Something went wrong deleting this tax class.'))
-            );
-        }
-        $this->getResponse()->representJson($responseContent);
-    }
+    protected $taxClassBuilder;
 
     /**
-     * Validate/Filter Tax Class Type
-     *
-     * @param string $classType
-     * @return string processed class type
-     * @throws \Magento\Framework\Model\Exception
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService
+     * @param \Magento\Tax\Service\V1\Data\TaxClassBuilder $taxClassBuilder
      */
-    protected function _processClassType($classType)
-    {
-        $validClassTypes = array(
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER,
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
-        );
-        if (!in_array($classType, $validClassTypes)) {
-            throw new \Magento\Framework\Model\Exception(__('Invalid type of tax class specified.'));
-        }
-        return $classType;
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService,
+        \Magento\Tax\Service\V1\Data\TaxClassBuilder $taxClassBuilder
+    ) {
+        $this->taxClassService = $taxClassService;
+        $this->taxClassBuilder = $taxClassBuilder;
+        parent::__construct($context);
     }
 
     /**
@@ -134,13 +63,13 @@ class Tax extends \Magento\Backend\App\Action
      *
      * @param string $className
      * @return string processed class name
-     * @throws \Magento\Framework\Model\Exception
+     * @throws \Magento\Framework\Exception\InputException
      */
     protected function _processClassName($className)
     {
         $className = trim($this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($className));
         if ($className == '') {
-            throw new \Magento\Framework\Model\Exception(__('Invalid name of tax class specified.'));
+            throw new InputException('Invalid name of tax class specified.');
         }
         return $className;
     }
@@ -154,24 +83,4 @@ class Tax extends \Magento\Backend\App\Action
     {
         return $this->_authorization->isAllowed('Magento_Tax::manage_tax');
     }
-
-    /**
-     * Set tax ignore notification flag and redirect back
-     *
-     * @return \Magento\Framework\App\ResponseInterface
-     */
-    public function ignoreTaxNotificationAction()
-    {
-        $section = $this->getRequest()->getParam('section');
-        if ($section) {
-            try {
-                $path = 'tax/notification/ignore_' . $section;
-                $this->_objectManager->get('\Magento\Core\Model\Resource\Config')->saveConfig($path, 1, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0);
-            } catch (Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-
-        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-    }
 }
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0073d13209ae5f5cc4c62c670e7b5594812e2d0
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxDelete.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Tax;
+
+class AjaxDelete extends \Magento\Tax\Controller\Adminhtml\Tax
+{
+    /**
+     * Delete Tax Class via AJAX
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $classId = (int)$this->getRequest()->getParam('class_id');
+        try {
+            $this->taxClassService->deleteTaxClass($classId);
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => true, 'error_message' => '')
+            );
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => false, 'error_message' => $e->getMessage())
+            );
+        } catch (\Exception $e) {
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array('success' => false, 'error_message' => __('Something went wrong deleting this tax class.'))
+            );
+        }
+        $this->getResponse()->representJson($responseContent);
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php
new file mode 100644
index 0000000000000000000000000000000000000000..9994e32c15d4b6dbfaab3312832222308bc2346c
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/AjaxSave.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Tax;
+
+class AjaxSave extends \Magento\Tax\Controller\Adminhtml\Tax
+{
+    /**
+     * Save Tax Class via AJAX
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $taxClassId = (int)$this->getRequest()->getPost('class_id') ?: null;
+
+            $taxClass = $this->taxClassBuilder
+                ->setClassType((string)$this->getRequest()->getPost('class_type'))
+                ->setClassName($this->_processClassName((string)$this->getRequest()->getPost('class_name')))
+                ->create();
+            if ($taxClassId) {
+                $this->taxClassService->updateTaxClass($taxClassId, $taxClass);
+            } else {
+                $taxClassId = $this->taxClassService->createTaxClass($taxClass);
+            }
+
+            $responseContent = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonEncode(
+                array(
+                    'success' => true,
+                    'error_message' => '',
+                    'class_id' => $taxClassId,
+                    'class_name' => $taxClass->getClassName()
+                )
+            );
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $responseContent = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
+                array('success' => false, 'error_message' => $e->getMessage(), 'class_id' => '', 'class_name' => '')
+            );
+        } catch (\Exception $e) {
+            $responseContent = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(
+                array(
+                    'success' => false,
+                    'error_message' => __('Something went wrong saving this tax class.'),
+                    'class_id' => '',
+                    'class_name' => ''
+                )
+            );
+        }
+        $this->getResponse()->representJson($responseContent);
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
new file mode 100644
index 0000000000000000000000000000000000000000..9ca7f97057a673bc222d6849822ce860ab7b43a8
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/Adminhtml/Tax/IgnoreTaxNotification.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller\Adminhtml\Tax;
+
+class IgnoreTaxNotification extends \Magento\Tax\Controller\Adminhtml\Tax
+{
+
+    /**
+     * Set tax ignore notification flag and redirect back
+     *
+     * @return \Magento\Framework\App\ResponseInterface
+     */
+    public function execute()
+    {
+        $section = $this->getRequest()->getParam('section');
+        if ($section) {
+            try {
+                $path = 'tax/notification/ignore_' . $section;
+                $this->_objectManager->get('\Magento\Core\Model\Resource\Config')->saveConfig($path, 1, \Magento\Framework\App\ScopeInterface::SCOPE_DEFAULT, 0);
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+
+        $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+    }
+}
diff --git a/app/code/Magento/Tax/Controller/RegistryConstants.php b/app/code/Magento/Tax/Controller/RegistryConstants.php
new file mode 100644
index 0000000000000000000000000000000000000000..505b47a39603decff809cf13ff9d3be8c5e7f177
--- /dev/null
+++ b/app/code/Magento/Tax/Controller/RegistryConstants.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Controller;
+
+/**
+ * Declarations of core registry keys used by the Tax module
+ *
+ */
+class RegistryConstants
+{
+    /**
+     * Registry key where current tax ID is stored
+     */
+    const CURRENT_TAX_RATE_ID = 'current_tax_rate_id';
+
+    /**
+     * Registry key where current tax rate form data is stored
+     */
+    const CURRENT_TAX_RATE_FORM_DATA = 'current_tax_rate_form_data';
+}
diff --git a/app/code/Magento/Tax/Helper/Data.php b/app/code/Magento/Tax/Helper/Data.php
index 60a3902074688bb99fca90c29a37f416b11347a6..76569e00913619cdead2f0b6dc4cdf3521d57ddb 100644
--- a/app/code/Magento/Tax/Helper/Data.php
+++ b/app/code/Magento/Tax/Helper/Data.php
@@ -25,8 +25,11 @@ namespace Magento\Tax\Helper;
 
 use Magento\Store\Model\Store;
 use Magento\Customer\Model\Address;
-use Magento\Tax\Model\Calculation;
 use Magento\Tax\Model\Config;
+use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder;
+use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder as QuoteDetailsItemBuilder;
+use Magento\Tax\Service\V1\TaxCalculationServiceInterface;
+use Magento\Customer\Model\Address\Converter as AddressConverter;
 
 /**
  * Catalog data helper
@@ -60,13 +63,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_config;
 
-    /**
-     * Tax calculator
-     *
-     * @var \Magento\Tax\Model\Calculation
-     */
-    protected $_calculation;
-
     /**
      * Postcode cut to this length when creating search templates
      *
@@ -125,19 +121,50 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_localeResolver;
 
+    /**
+     * Quote details builder
+     *
+     * @var QuoteDetailsBuilder
+     */
+    protected $quoteDetailsBuilder;
+
+    /**
+     * Quote details item builder
+     *
+     * @var QuoteDetailsItemBuilder
+     */
+    protected $quoteDetailsItemBuilder;
+
+    /**
+     * Tax calculation service
+     *
+     * @var TaxCalculationServiceInterface
+     */
+    protected $taxCalculationService;
+
+    /**
+     * Address converter
+     *
+     * @var AddressConverter
+     */
+    protected $addressConverter;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Core\Helper\Data $coreData
      * @param \Magento\Framework\Registry $coreRegistry
      * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      * @param Config $taxConfig
-     * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Framework\Locale\FormatInterface $localeFormat
      * @param \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory
      * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory
      * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory
      * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
+     * @param QuoteDetailsBuilder $quoteDetailsBuilder
+     * @param QuoteDetailsItemBuilder $quoteDetailsItemBuilder
+     * @param TaxCalculationServiceInterface $taxCalculationService
+     * @param AddressConverter $addressConverter
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
@@ -145,26 +172,32 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Framework\Registry $coreRegistry,
         \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
         Config $taxConfig,
-        \Magento\Tax\Model\Calculation $calculation,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Framework\Locale\FormatInterface $localeFormat,
         \Magento\Eav\Model\Entity\AttributeFactory $attributeFactory,
         \Magento\Tax\Model\Resource\Sales\Order\Tax\ItemFactory $taxItemFactory,
         \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $orderTaxCollectionFactory,
-        \Magento\Framework\Locale\ResolverInterface $localeResolver
+        \Magento\Framework\Locale\ResolverInterface $localeResolver,
+        QuoteDetailsBuilder $quoteDetailsBuilder,
+        QuoteDetailsItemBuilder $quoteDetailsItemBuilder,
+        TaxCalculationServiceInterface $taxCalculationService,
+        AddressConverter $addressConverter
     ) {
         parent::__construct($context);
         $this->_scopeConfig = $scopeConfig;
         $this->_config = $taxConfig;
         $this->_coreData = $coreData;
         $this->_coreRegistry = $coreRegistry;
-        $this->_calculation = $calculation;
         $this->_storeManager = $storeManager;
         $this->_localeFormat = $localeFormat;
         $this->_attributeFactory = $attributeFactory;
         $this->_taxItemFactory = $taxItemFactory;
         $this->_orderTaxCollectionFactory = $orderTaxCollectionFactory;
         $this->_localeResolver = $localeResolver;
+        $this->quoteDetailsBuilder = $quoteDetailsBuilder;
+        $this->quoteDetailsItemBuilder = $quoteDetailsItemBuilder;
+        $this->taxCalculationService = $taxCalculationService;
+        $this->addressConverter = $addressConverter;
     }
 
     /**
@@ -191,22 +224,13 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->_config;
     }
 
-    /**
-     * Get tax calculation object
-     *
-     * @return \Magento\Tax\Model\Calculation
-     */
-    public function getCalculator()
-    {
-        return $this->_calculation;
-    }
-
     /**
      * Get product price including store convertion rate
      *
      * @param \Magento\Catalog\Model\Product $product
      * @param null|string $format
      * @return float|string
+     * @deprecated
      */
     public function getProductPrice($product, $format = null)
     {
@@ -454,34 +478,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->_coreData->jsonEncode($priceFormat);
     }
 
-    /**
-     * Get all tax rates JSON for all product tax classes of specific store
-     *
-     * @param null|string|bool|int|Store $store
-     * @return string
-     */
-    public function getAllRatesByProductClass($store = null)
-    {
-        return $this->_getAllRatesByProductClass($store);
-    }
-
-    /**
-     * Get all tax rates JSON for all product tax classes of specific store
-     *
-     * @param null|string|bool|int|Store $store
-     * @return string
-     */
-    protected function _getAllRatesByProductClass($store = null)
-    {
-        $result = array();
-        $defaultRate = $this->_calculation->getDefaultRateRequest($store);
-        $rates = $this->_calculation->getRatesForAllProductTaxClasses($defaultRate);
-        foreach ($rates as $class => $rate) {
-            $result["value_{$class}"] = $rate;
-        }
-        return $this->_coreData->jsonEncode($result);
-    }
-
     /**
      * Get unrounded product price
      *
@@ -546,113 +542,75 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         if (!$price) {
             return $price;
         }
-        $store = $this->_storeManager->getStore($store);
-        if (!$this->needPriceConversion($store)) {
-            return $store->roundPrice($price);
-        }
-        if (is_null($priceIncludesTax)) {
-            $priceIncludesTax = $this->priceIncludesTax($store);
-        }
 
-        $percent = $product->getTaxPercent();
-        $includingPercent = null;
-
-        $taxClassId = $product->getTaxClassId();
-        if (is_null($percent)) {
-            if ($taxClassId) {
-                $request = $this->_calculation->getRateRequest($shippingAddress, $billingAddress, $ctc, $store);
-                $percent = $this->_calculation->getRate($request->setProductClassId($taxClassId));
+        $store = $this->_storeManager->getStore($store);
+        if ($this->needPriceConversion($store)) {
+            if (is_null($priceIncludesTax)) {
+                $priceIncludesTax = $this->priceIncludesTax($store);
             }
-        }
-        if ($taxClassId && $priceIncludesTax) {
-            if ($this->isCrossBorderTradeEnabled($store)) {
-                $includingPercent = $percent;
-            } else {
-                $request = $this->_calculation->getRateOriginRequest($store);
-                $includingPercent = $this->_calculation->getRate($request->setProductClassId($taxClassId));
+
+            $shippingAddressDataObject = null;
+            if ($shippingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) {
+                $shippingAddressDataObject = $this->addressConverter->createAddressFromModel(
+                    $shippingAddress,
+                    null,
+                    null
+                );
             }
-        }
 
-        if ($percent === false || is_null($percent)) {
-            if ($priceIncludesTax && !$includingPercent) {
-                return $price;
+            $billingAddressDataObject = null;
+            if ($billingAddress instanceof \Magento\Customer\Model\Address\AbstractAddress) {
+                $billingAddressDataObject = $this->addressConverter->createAddressFromModel(
+                    $billingAddress,
+                    null,
+                    null
+                );
             }
-        }
 
-        $product->setTaxPercent($percent);
-        if ($product->getAppliedRates() == null) {
-            $request = $this->_calculation->getRateRequest($shippingAddress, $billingAddress, $ctc, $store);
-            $request->setProductClassId($taxClassId);
-            $appliedRates = $this->_calculation->getAppliedRates($request);
-            $product->setAppliedRates($appliedRates);
-        }
+            $item = $this->quoteDetailsItemBuilder->setQuantity(1)
+                ->setCode($product->getSku())
+                ->setShortDescription($product->getShortDescription())
+                ->setTaxClassId($product->getTaxClassId())
+                ->setTaxIncluded($priceIncludesTax)
+                ->setType('product')
+                ->setUnitPrice($price)
+                ->create();
+            $quoteDetails = $this->quoteDetailsBuilder
+                ->setShippingAddress($shippingAddressDataObject)
+                ->setBillingAddress($billingAddressDataObject)
+                ->setCustomerTaxClassId($ctc)
+                ->setItems([$item])
+                ->create();
+
+            $storeId = null;
+            if ($store) {
+                $storeId = $store->getId();
+            }
+            $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails, $storeId);
+            $items = $taxDetails->getItems();
+            $taxDetailsItem = array_shift($items);
 
-        if (!is_null($includingTax)) {
-            if ($priceIncludesTax) {
+            if (!is_null($includingTax)) {
                 if ($includingTax) {
-                    /**
-                     * Recalculate price include tax in case of different rates.  Otherwise price remains the same.
-                     */
-                    if ($includingPercent != $percent) {
-                        // determine the customer's price that includes tax
-                        $price = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store);
-                    }
+                    $price = $taxDetailsItem->getPriceInclTax();
                 } else {
-                    $price = $this->_calculatePrice($price, $includingPercent, false);
+                    $price = $taxDetailsItem->getPrice();
                 }
             } else {
-                if ($includingTax) {
-                    $appliedRates = $product->getAppliedRates();
-                    if (count($appliedRates) > 1) {
-                        $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates);
-                    } else {
-                        $price = $this->_calculatePrice($price, $percent, true);
-                    }
-                }
-            }
-        } else {
-            if ($priceIncludesTax) {
                 switch ($this->getPriceDisplayType($store)) {
                     case Config::DISPLAY_TYPE_EXCLUDING_TAX:
                     case Config::DISPLAY_TYPE_BOTH:
-                        if ($includingPercent != $percent) {
-                            // determine the customer's price that includes tax
-                            $taxablePrice = $this->_calculatePriceInclTax($price, $includingPercent, $percent, $store);
-                            // determine the customer's tax amount,
-                            // round tax unless $roundPrice is set explicitly to false
-                            $tax = $this->_calculation->calcTaxAmount($taxablePrice, $percent, true, $roundPrice);
-                            // determine the customer's price without taxes
-                            $price = $taxablePrice - $tax;
-                        } else {
-                            //round tax first unless $roundPrice is set to false explicitly
-                            $price = $this->_calculatePrice($price, $includingPercent, false, $roundPrice);
-                        }
+                        $price = $taxDetailsItem->getPrice();
                         break;
                     case Config::DISPLAY_TYPE_INCLUDING_TAX:
-                        $price = $this->_calculatePrice($price, $includingPercent, false);
-                        $price = $this->_calculatePrice($price, $percent, true);
-                        break;
-                    default:
-                        break;
-                }
-            } else {
-                switch ($this->getPriceDisplayType($store)) {
-                    case Config::DISPLAY_TYPE_INCLUDING_TAX:
-                        $appliedRates = $product->getAppliedRates();
-                        if (count($appliedRates) > 1) {
-                            $price = $this->_calculatePriceInclTaxWithMultipleRates($price, $appliedRates);
-                        } else {
-                            $price = $this->_calculatePrice($price, $percent, true);
-                        }
-                        break;
-                    case Config::DISPLAY_TYPE_BOTH:
-                    case Config::DISPLAY_TYPE_EXCLUDING_TAX:
+                        $price = $taxDetailsItem->getPriceInclTax();
                         break;
                     default:
                         break;
                 }
             }
         }
+
         if ($roundPrice) {
             return $store->roundPrice($price);
         } else {
@@ -660,24 +618,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         }
     }
 
-    /**
-     * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in
-     * the customer's tax.  Returns this new price which is the customer's price including tax.
-     *
-     * @param float $storePriceInclTax
-     * @param float $storePercent
-     * @param float $customerPercent
-     * @param null|int|string|Store $store
-     * @return float
-     */
-    protected function _calculatePriceInclTax($storePriceInclTax, $storePercent, $customerPercent, $store)
-    {
-        $priceExclTax         = $this->_calculatePrice($storePriceInclTax, $storePercent, false, false);
-        $customerTax          = $this->_calculation->calcTaxAmount($priceExclTax, $customerPercent, false, false);
-        $customerPriceInclTax = $store->roundPrice($priceExclTax + $customerTax);
-        return $customerPriceInclTax;
-    }
-
     /**
      * Check if we have display in catalog prices including tax
      *
@@ -709,43 +649,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $this->getPriceDisplayType($store) == Config::DISPLAY_TYPE_BOTH;
     }
 
-    /**
-     * Calculate price including/excluding tax based on tax rate percent
-     *
-     * @param   float $price
-     * @param   float $percent
-     * @param   bool  $type - true to calculate the price including tax or false if calculating price to exclude tax
-     * @param   bool  $roundTaxFirst
-     * @return  float
-     */
-    protected function _calculatePrice($price, $percent, $type, $roundTaxFirst = false)
-    {
-        if ($type) {
-            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, false, $roundTaxFirst);
-            return $price + $taxAmount;
-        } else {
-            $taxAmount = $this->_calculation->calcTaxAmount($price, $percent, true, $roundTaxFirst);
-            return $price - $taxAmount;
-        }
-    }
-
-    /**
-     * Calculate price including tax when multiple taxes is applied and rounded independently.
-     *
-     * @param  float $price
-     * @param  array $appliedRates
-     * @return float
-     */
-    protected function _calculatePriceInclTaxWithMultipleRates($price, $appliedRates)
-    {
-        $tax = 0;
-        foreach ($appliedRates as $appliedRate) {
-            $taxRate = $appliedRate['percent'];
-            $tax += $this->_calculation->round($price * $taxRate / 100);
-        }
-        return $tax + $price;
-    }
-
     /**
      * Returns the include / exclude tax label
      *
@@ -854,106 +757,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         return $price;
     }
 
-    /**
-     * Returns the SQL for the price tax
-     *
-     * @param string $priceField
-     * @param string $taxClassField
-     * @return string
-     */
-    public function getPriceTaxSql($priceField, $taxClassField)
-    {
-        if (!$this->priceIncludesTax() && $this->displayPriceExcludingTax()) {
-            return '';
-        }
-
-        $request = $this->_calculation->getDefaultRateRequest();
-        $defaultTaxes = $this->_calculation->getRatesForAllProductTaxClasses($request);
-
-        $request = $this->_calculation->getRateRequest();
-        $currentTaxes = $this->_calculation->getRatesForAllProductTaxClasses($request);
-
-        $defaultTaxString = $currentTaxString = '';
-
-        $rateToVariable = array(
-            'defaultTaxString' => 'defaultTaxes',
-            'currentTaxString' => 'currentTaxes',
-        );
-        foreach ($rateToVariable as $rateVariable => $rateArray) {
-            if (${$rateArray} && is_array(${$rateArray})) {
-                ${$rateVariable} = '';
-                foreach (${$rateArray} as $classId => $rate) {
-                    if ($rate) {
-                        ${$rateVariable} .= sprintf("WHEN %d THEN %12.4F ", $classId, $rate / 100);
-                    }
-                }
-                if (${$rateVariable}) {
-                    ${$rateVariable} = "CASE {$taxClassField} {${$rateVariable}} ELSE 0 END";
-                }
-            }
-        }
-
-        $result = '';
-
-        if ($this->priceIncludesTax()) {
-            if ($defaultTaxString) {
-                $result = "-({$priceField}/(1+({$defaultTaxString}))*{$defaultTaxString})";
-            }
-            if (!$this->displayPriceExcludingTax() && $currentTaxString) {
-                $result .= "+(({$priceField}{$result})*{$currentTaxString})";
-            }
-        } else {
-            if ($this->displayPriceIncludingTax()) {
-                if ($currentTaxString) {
-                    $result .= "+({$priceField}*{$currentTaxString})";
-                }
-            }
-        }
-        return $result;
-    }
-
-    /**
-     * Join tax class
-     * @param \Magento\Framework\DB\Select $select
-     * @param int $storeId
-     * @param string $priceTable
-     * @return $this
-     */
-    public function joinTaxClass($select, $storeId, $priceTable = 'main_table')
-    {
-        /** @var $taxClassAttribute \Magento\Eav\Model\Entity\Attribute */
-        $taxClassAttribute = $this->_attributeFactory->create();
-        $taxClassAttribute->loadByCode(\Magento\Catalog\Model\Product::ENTITY, 'tax_class_id');
-        $joinConditionD = implode(
-            ' AND ',
-            array(
-                "tax_class_d.entity_id = {$priceTable}.entity_id",
-                $select->getAdapter()->quoteInto('tax_class_d.attribute_id = ?', (int) $taxClassAttribute->getId()),
-                'tax_class_d.store_id = 0'
-            )
-        );
-        $joinConditionC = implode(
-            ' AND ',
-            array(
-                "tax_class_c.entity_id = {$priceTable}.entity_id",
-                $select->getAdapter()->quoteInto('tax_class_c.attribute_id = ?', (int) $taxClassAttribute->getId()),
-                $select->getAdapter()->quoteInto('tax_class_c.store_id = ?', (int) $storeId)
-            )
-        );
-        $select
-            ->joinLeft(
-                array('tax_class_d' => $taxClassAttribute->getBackend()->getTable()),
-                $joinConditionD,
-                array()
-            )->joinLeft(
-                array('tax_class_c' => $taxClassAttribute->getBackend()->getTable()),
-                $joinConditionC,
-                array()
-            );
-
-        return $this;
-    }
-
     /**
      * Get configuration setting "Apply Discount On Prices Including Tax" value
      *
diff --git a/app/code/Magento/Tax/Model/Calculation.php b/app/code/Magento/Tax/Model/Calculation.php
index 8e079068752877a9678064f6b81bce0d2146e22b..ab4fddc830125d79760597c6d8da93d13f248835 100644
--- a/app/code/Magento/Tax/Model/Calculation.php
+++ b/app/code/Magento/Tax/Model/Calculation.php
@@ -225,18 +225,6 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         $this->_init('Magento\Tax\Model\Resource\Calculation');
     }
 
-    /**
-     * Specify customer object which can be used for rate calculation
-     *
-     * @param CustomerDataObject $customerData
-     * @return $this
-     */
-    public function setCustomerData(CustomerDataObject $customerData)
-    {
-        $this->_customer = $customerData;
-        return $this;
-    }
-
     /**
      * Fetch default customer tax class
      *
@@ -253,26 +241,6 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
         return $this->_defaultCustomerTaxClass;
     }
 
-    /**
-     * Retrieve customer data object
-     *
-     * @return CustomerDataObject
-     */
-    public function getCustomerData()
-    {
-        if ($this->_customer === null) {
-            if ($this->_customerSession->isLoggedIn()) {
-                $this->_customer = $this->_customerSession->getCustomerDataObject();
-            } elseif ($this->_customerSession->getCustomerId()) {
-                $this->_customer = $this->customerAccountService->getCustomer($this->_customerSession->getCustomerId());
-            } else {
-                $this->_customer = $this->customerBuilder->create();
-            }
-        }
-
-        return $this->_customer;
-    }
-
     /**
      * Delete calculation settings by rule id
      *
@@ -457,13 +425,14 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
      * Return the default rate request. It can be either based on store address or customer address
      *
      * @param null|int|string|Store $store
+     * @param int $customerId
      * @return \Magento\Framework\Object
      */
-    public function getDefaultRateRequest($store = null)
+    public function getDefaultRateRequest($store = null, $customerId = null)
     {
         if ($this->_isCrossBorderTradeEnabled($store)) {
             //If cross border trade is enabled, we will use customer tax rate as store tax rate
-            return $this->getRateRequest(null, null, null, $store);
+            return $this->getRateRequest(null, null, null, $store, $customerId);
         } else {
             return $this->getRateOriginRequest($store);
         }
@@ -490,23 +459,24 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
      *  customer_class_id (->getCustomerClassId())
      *  store (->getStore())
      *
-     * @param   null|bool|\Magento\Framework\Object|\Magento\Customer\Service\V1\Data\Address $shippingAddress
-     * @param   null|bool|\Magento\Framework\Object|\Magento\Customer\Service\V1\Data\Address $billingAddress
-     * @param   null|int $customerTaxClass
-     * @param   null|int|\Magento\Store\Model\Store $store
+     * @param null|bool|\Magento\Framework\Object|\Magento\Customer\Service\V1\Data\Address $shippingAddress
+     * @param null|bool|\Magento\Framework\Object|\Magento\Customer\Service\V1\Data\Address $billingAddress
+     * @param null|int $customerTaxClass
+     * @param null|int|\Magento\Store\Model\Store $store
+     * @param int $customerId
      * @return  \Magento\Framework\Object
      */
     public function getRateRequest(
         $shippingAddress = null,
         $billingAddress = null,
         $customerTaxClass = null,
-        $store = null
+        $store = null,
+        $customerId = null
     ) {
         if ($shippingAddress === false && $billingAddress === false && $customerTaxClass === false) {
             return $this->getRateOriginRequest($store);
         }
         $address = new \Magento\Framework\Object();
-        $customerData = $this->getCustomerData();
         $basedOn = $this->_scopeConfig->getValue(
             \Magento\Tax\Model\Config::CONFIG_XML_PATH_BASED_ON,
             \Magento\Store\Model\ScopeInterface::SCOPE_STORE,
@@ -518,19 +488,19 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
             $basedOn = 'default';
         } else {
 
-            if (($billingAddress === false || is_null($billingAddress) || !$billingAddress->getCountryId())
+            if ((is_null($billingAddress) || !$billingAddress->getCountryId())
                 && $basedOn == 'billing'
-                || ($shippingAddress === false || is_null($shippingAddress) || !$shippingAddress->getCountryId())
+                || (is_null($shippingAddress) || !$shippingAddress->getCountryId())
                 && $basedOn == 'shipping'
             ) {
-                if ($customerData->getId()) {
+                if ($customerId) {
                     try {
-                        $defaultBilling = $this->_addressService->getDefaultBillingAddress($customerData->getId());
+                        $defaultBilling = $this->_addressService->getDefaultBillingAddress($customerId);
                     } catch (NoSuchEntityException $e) {
                     }
 
                     try {
-                        $defaultShipping = $this->_addressService->getDefaultShippingAddress($customerData->getId());
+                        $defaultShipping = $this->_addressService->getDefaultShippingAddress($customerId);
                     } catch (NoSuchEntityException $e) {
                     }
 
@@ -582,10 +552,13 @@ class Calculation extends \Magento\Framework\Model\AbstractModel
                 break;
         }
 
-        if (is_null($customerTaxClass) && $customerData->getId()) {
+        if (is_null($customerTaxClass) && $customerId) {
+            $customerData = $this->customerAccountService->getCustomer($customerId);
             $customerTaxClass = $this->_groupService->getGroup($customerData->getGroupId())->getTaxClassId();
-        } elseif ($customerTaxClass === false && !$customerData->getId()) {
-            $customerTaxClass = $this->_groupService->getGroup(GroupServiceInterface::NOT_LOGGED_IN_ID)->getTaxClassId();
+        } elseif ($customerTaxClass === false && !$customerId) {
+            $customerTaxClass = $this->_groupService
+                ->getGroup(GroupServiceInterface::NOT_LOGGED_IN_ID)
+                ->getTaxClassId();
         }
 
         $request = new \Magento\Framework\Object();
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
index 4f2c538cad536efeacda36239283cb7b74338ccd..c1233084b4d4fb74eacf0dbfadc97275c63b8829 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
@@ -23,10 +23,12 @@
  */
 namespace Magento\Tax\Model\Calculation\Rate;
 
+use Magento\Directory\Model\Region;
 use Magento\Tax\Model\Calculation\Rate as TaxRateModel;
 use Magento\Tax\Model\Calculation\RateFactory as TaxRateModelFactory;
 use Magento\Tax\Service\V1\Data\TaxRate as TaxRateDataObject;
 use Magento\Tax\Service\V1\Data\TaxRateBuilder as TaxRateDataObjectBuilder;
+use Magento\Tax\Service\V1\Data\TaxRateTitleBuilder as TaxRateTitleDataObjectBuilder;
 use Magento\Tax\Service\V1\Data\ZipRangeBuilder as ZipRangeDataObjectBuilder;
 
 /**
@@ -51,19 +53,35 @@ class Converter
      */
     protected $zipRangeDataObjectBuilder;
 
+    /**
+     * @var TaxRateTitleDataObjectBuilder
+     */
+    protected $taxRateTitleDataObjectBuilder;
+
+    /**
+     * @var Region
+     */
+    protected $directoryRegion;
+
     /**
      * @param TaxRateDataObjectBuilder $taxRateDataObjectBuilder
      * @param TaxRateModelFactory $taxRateModelFactory
      * @param ZipRangeDataObjectBuilder $zipRangeDataObjectBuilder
+     * @param TaxRateTitleDataObjectBuilder $taxRateTitleDataObjectBuilder
+     * @param Region $directoryRegion
      */
     public function __construct(
         TaxRateDataObjectBuilder $taxRateDataObjectBuilder,
         TaxRateModelFactory $taxRateModelFactory,
-        ZipRangeDataObjectBuilder $zipRangeDataObjectBuilder
+        ZipRangeDataObjectBuilder $zipRangeDataObjectBuilder,
+        TaxRateTitleDataObjectBuilder $taxRateTitleDataObjectBuilder,
+        Region $directoryRegion
     ) {
         $this->taxRateDataObjectBuilder = $taxRateDataObjectBuilder;
         $this->taxRateModelFactory = $taxRateModelFactory;
         $this->zipRangeDataObjectBuilder = $zipRangeDataObjectBuilder;
+        $this->taxRateTitleDataObjectBuilder = $taxRateTitleDataObjectBuilder;
+        $this->directoryRegion = $directoryRegion;
     }
 
     /**
@@ -71,6 +89,7 @@ class Converter
      *
      * @param TaxRateModel $rateModel
      * @return TaxRateDataObject
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function createTaxRateDataObjectFromModel(TaxRateModel $rateModel)
     {
@@ -81,8 +100,14 @@ class Converter
         if ($rateModel->getTaxCountryId()) {
             $this->taxRateDataObjectBuilder->setCountryId($rateModel->getTaxCountryId());
         }
-        if ($rateModel->getTaxRegionId()) {
+        /* tax region id may be 0 which is "*" which would fail an if check */
+        if ($rateModel->getTaxRegionId() !== null) {
             $this->taxRateDataObjectBuilder->setRegionId($rateModel->getTaxRegionId());
+            $regionName = $this->directoryRegion->load($rateModel->getTaxRegionId())->getCode();
+            $this->taxRateDataObjectBuilder->setRegionName($regionName);
+        }
+        if ($rateModel->getRegionName()) {
+            $this->taxRateDataObjectBuilder->setRegionName($rateModel->getRegionName());
         }
         if ($rateModel->getTaxPostcode()) {
             $this->taxRateDataObjectBuilder->setPostcode($rateModel->getTaxPostcode());
@@ -91,7 +116,7 @@ class Converter
             $this->taxRateDataObjectBuilder->setCode($rateModel->getCode());
         }
         if ($rateModel->getRate()) {
-            $this->taxRateDataObjectBuilder->setPercentageRate($rateModel->getRate());
+            $this->taxRateDataObjectBuilder->setPercentageRate((float)$rateModel->getRate());
         }
         if ($rateModel->getZipIsRange()) {
             $zipRange = $this->zipRangeDataObjectBuilder->populateWithArray([])
@@ -100,6 +125,7 @@ class Converter
                 ->create();
             $this->taxRateDataObjectBuilder->setZipRange($zipRange);
         }
+        $this->taxRateDataObjectBuilder->setTitles($this->createTitleArrayFromModel($rateModel));
         return $this->taxRateDataObjectBuilder->create();
     }
 
@@ -121,6 +147,7 @@ class Converter
         $rateModel->setRate($taxRate->getPercentageRate());
         $rateModel->setCode($taxRate->getCode());
         $rateModel->setTaxPostcode($taxRate->getPostCode());
+        $rateModel->setRegionName($taxRate->getRegionName());
         $zipRange = $taxRate->getZipRange();
         if ($zipRange) {
             $zipFrom = $zipRange->getFrom();
@@ -133,4 +160,43 @@ class Converter
         }
         return $rateModel;
     }
+
+    /**
+     * Convert a tax rate data object to an array of associated titles
+     *
+     * @param TaxRateDataObject $taxRate
+     * @return array
+     */
+    public function createTitleArrayFromServiceObject(TaxRateDataObject $taxRate)
+    {
+        $titles = $taxRate->getTitles();
+        $titleData = [];
+        if ($titles) {
+            foreach ($titles as $title) {
+                $titleData[$title->getStoreId()] = $title->getValue();
+            }
+        }
+        return $titleData;
+    }
+
+    /**
+     * Create an array with tax rate titles having tax rate model.
+     *
+     * @param TaxRateModel $rateModel
+     * @return array
+     */
+    public function createTitleArrayFromModel(TaxRateModel $rateModel)
+    {
+        $titlesData = $rateModel->getTitles();
+        $titles = [];
+        if ($titlesData) {
+            foreach ($titlesData as $title) {
+                $titles[] = $this->taxRateTitleDataObjectBuilder
+                    ->setStoreId($title->getStoreId())
+                    ->setValue($title->getValue())
+                    ->create();
+            }
+        }
+        return $titles;
+    }
 }
diff --git a/app/code/Magento/Tax/Model/Calculation/Rule.php b/app/code/Magento/Tax/Model/Calculation/Rule.php
index 86bd3f79decdacc2c9521c0d0643dc3a3617511c..b5da6481696a378a953d4b5551939ceafbedb44c 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rule.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rule.php
@@ -44,13 +44,6 @@ class Rule extends \Magento\Framework\Model\AbstractModel
      */
     protected $_eventPrefix = 'tax_rule';
 
-    /**
-     * Helper
-     *
-     * @var \Magento\Tax\Helper\Data
-     */
-    protected $_helper;
-
     /**
      * Tax Model Class
      *
@@ -66,7 +59,6 @@ class Rule extends \Magento\Framework\Model\AbstractModel
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Tax\Helper\Data $taxHelper
      * @param \Magento\Tax\Model\ClassModel $taxClass
      * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Framework\Model\Resource\AbstractResource $resource
@@ -76,7 +68,6 @@ class Rule extends \Magento\Framework\Model\AbstractModel
     public function __construct(
         \Magento\Framework\Model\Context $context,
         \Magento\Framework\Registry $registry,
-        \Magento\Tax\Helper\Data $taxHelper,
         \Magento\Tax\Model\ClassModel $taxClass,
         \Magento\Tax\Model\Calculation $calculation,
         \Magento\Framework\Model\Resource\AbstractResource $resource = null,
@@ -88,7 +79,6 @@ class Rule extends \Magento\Framework\Model\AbstractModel
 
         $this->_init('Magento\Tax\Model\Resource\Calculation\Rule');
 
-        $this->_helper = $taxHelper;
         $this->_taxClass = $taxClass;
     }
 
@@ -175,61 +165,6 @@ class Rule extends \Magento\Framework\Model\AbstractModel
         return $this->getCalculationModel()->getProductTaxClasses($this->getId());
     }
 
-    /**
-     * Check Customer Tax Class and if it is empty - use defaults
-     *
-     * @return int|array|null
-     */
-    public function getCustomerTaxClassWithDefault()
-    {
-        $customerClasses = $this->getAllOptionsForClass(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER);
-        if (empty($customerClasses)) {
-            return null;
-        }
-
-        $configValue = $this->_helper->getDefaultCustomerTaxClass();
-        if (!empty($configValue)) {
-            return $configValue;
-        }
-
-        $firstClass = array_shift($customerClasses);
-        return isset($firstClass['value']) ? $firstClass['value'] : null;
-    }
-
-    /**
-     * Check Product Tax Class and if it is empty - use defaults
-     *
-     * @return int|array|null
-     */
-    public function getProductTaxClassWithDefault()
-    {
-        $productClasses = $this->getAllOptionsForClass(\Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT);
-        if (empty($productClasses)) {
-            return null;
-        }
-
-        $configValue = $this->_helper->getDefaultProductTaxClass();
-        if (!empty($configValue)) {
-            return $configValue;
-        }
-
-        $firstClass = array_shift($productClasses);
-        return isset($firstClass['value']) ? $firstClass['value'] : null;
-    }
-
-    /**
-     * Get all possible options for specified class name (customer|product)
-     *
-     * @param string $classFilter
-     * @return array
-     */
-    public function getAllOptionsForClass($classFilter)
-    {
-        $classes = $this->_taxClass->getCollection()->setClassTypeFilter($classFilter)->toOptionArray();
-
-        return $classes;
-    }
-
     /**
      * Fetches rules by rate, customer tax class and product tax class
      * and product tax class combination
diff --git a/app/code/Magento/Tax/Model/Calculation/TaxRuleConverter.php b/app/code/Magento/Tax/Model/Calculation/TaxRuleConverter.php
index cff63dfd5cb9587075221eaeb9490033f78344b9..17ddb53dd55079edb2367ce88aa2354048d19bc7 100644
--- a/app/code/Magento/Tax/Model/Calculation/TaxRuleConverter.php
+++ b/app/code/Magento/Tax/Model/Calculation/TaxRuleConverter.php
@@ -90,6 +90,9 @@ class TaxRuleConverter
         if (!is_null($ruleModel->getPosition())) {
             $this->taxRuleDataObjectBuilder->setSortOrder($ruleModel->getPosition());
         }
+        if (!is_null($ruleModel->getCalculateSubtotal())) {
+            $this->taxRuleDataObjectBuilder->setCalculateSubtotal($ruleModel->getCalculateSubtotal());
+        }
         return $this->taxRuleDataObjectBuilder->create();
     }
 
@@ -112,6 +115,7 @@ class TaxRuleConverter
         $taxRuleModel->setCode($taxRuleDataObject->getCode());
         $taxRuleModel->setPriority($taxRuleDataObject->getPriority());
         $taxRuleModel->setPosition($taxRuleDataObject->getSortOrder());
+        $taxRuleModel->setCalculateSubtotal($taxRuleDataObject->getCalculateSubtotal());
         return $taxRuleModel;
     }
 
diff --git a/app/code/Magento/Tax/Model/ClassModel.php b/app/code/Magento/Tax/Model/ClassModel.php
index 7d0e2302e7b2ee826b938e7ec560bb026a84e324..7fa71e7ab1d6ef0575d6be50b75eae0b5eca7abe 100644
--- a/app/code/Magento/Tax/Model/ClassModel.php
+++ b/app/code/Magento/Tax/Model/ClassModel.php
@@ -24,6 +24,8 @@
 
 namespace Magento\Tax\Model;
 
+use Magento\Framework\Exception\CouldNotDeleteException;
+
 /**
  * Tax class model
  *
@@ -83,30 +85,27 @@ class ClassModel extends \Magento\Framework\Model\AbstractModel
      * Check whether this class can be deleted
      *
      * @return bool
-     * @throws \Magento\Framework\Model\Exception
+     * @throws CouldNotDeleteException
      */
     protected function checkClassCanBeDeleted()
     {
         if (!$this->getId()) {
-            throw new \Magento\Framework\Model\Exception(__('This class no longer exists.'));
+            throw new CouldNotDeleteException('This class no longer exists.');
         }
 
         $typeModel = $this->_classFactory->create($this);
 
         if ($typeModel->getAssignedToRules()->getSize() > 0) {
-            throw new \Magento\Framework\Model\Exception(
-                __(
-                    'You cannot delete this tax class because it is used in Tax Rules. You have to delete the rules it is used in first.'
-                )
+            throw new CouldNotDeleteException(
+                'You cannot delete this tax class because it is used in Tax Rules.' .
+                ' You have to delete the rules it is used in first.'
             );
         }
 
         if ($typeModel->isAssignedToObjects()) {
-            throw new \Magento\Framework\Model\Exception(
-                __(
-                    'You cannot delete this tax class because it is used in existing %1(s).',
-                    $typeModel->getObjectTypeName()
-                )
+            throw new CouldNotDeleteException(
+                'You cannot delete this tax class because it is used in existing %object(s).',
+                ['object' => $typeModel->getObjectTypeName()]
             );
         }
 
diff --git a/app/code/Magento/Tax/Model/ClassModelRegistry.php b/app/code/Magento/Tax/Model/ClassModelRegistry.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9fb2f088feab51ae6c6cd1f06a48cf076608415
--- /dev/null
+++ b/app/code/Magento/Tax/Model/ClassModelRegistry.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model;
+
+use Magento\Tax\Model\ClassModelFactory as TaxClassModelFactory;
+use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Tax\Model\ClassModel as TaxClassModel;
+use Magento\Tax\Service\V1\Data\TaxClass;
+
+/**
+ * Registry for the tax class models
+ */
+class ClassModelRegistry
+{
+    /**
+     * Tax class model factory
+     *
+     * @var TaxClassModelFactory
+     */
+    private $taxClassModelFactory;
+
+    /**
+     * Tax class models
+     *
+     * @var TaxClassModel[]
+     */
+    private $taxClassRegistryById = [];
+
+    /**
+     * Initialize dependencies
+     *
+     * @param TaxClassModelFactory $taxClassModelFactory
+     */
+    public function __construct(TaxClassModelFactory $taxClassModelFactory)
+    {
+        $this->taxClassModelFactory = $taxClassModelFactory;
+    }
+
+    /**
+     * Add tax class model to the registry
+     *
+     * @param TaxClassModel $taxClassModel
+     * @return void
+     */
+    public function registerTaxClass(TaxClassModel $taxClassModel)
+    {
+        $this->taxClassRegistryById[$taxClassModel->getId()] = $taxClassModel;
+    }
+
+    /**
+     * Retrieve tax class model from the registry
+     *
+     * @param int $taxClassId
+     * @return TaxClassModel
+     * @throws NoSuchEntityException
+     */
+    public function retrieve($taxClassId)
+    {
+        if (isset($this->taxClassRegistryById[$taxClassId])) {
+            return $this->taxClassRegistryById[$taxClassId];
+        }
+        /** @var TaxClassModel $taxClassModel */
+        $taxClassModel = $this->taxClassModelFactory->create()->load($taxClassId);
+        if (!$taxClassModel->getId()) {
+            // tax class does not exist
+            throw NoSuchEntityException::singleField(TaxClass::KEY_ID, $taxClassId);
+        }
+        $this->taxClassRegistryById[$taxClassModel->getId()] = $taxClassModel;
+        return $taxClassModel;
+    }
+
+    /**
+     * Remove an instance of the tax class model from the registry
+     *
+     * @param int $taxClassId
+     * @return void
+     */
+    public function remove($taxClassId)
+    {
+        unset($this->taxClassRegistryById[$taxClassId]);
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Config/Source/TaxClass/Customer.php b/app/code/Magento/Tax/Model/Config/Source/TaxClass/Customer.php
deleted file mode 100644
index 1c70a72b2df01e9118950d6ca3db1aaac18503ff..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/Model/Config/Source/TaxClass/Customer.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Tax\Model\Config\Source\TaxClass;
-
-class Customer implements \Magento\Framework\Option\ArrayInterface
-{
-    /**
-     * @var \Magento\Tax\Model\TaxClass\Source\CustomerFactory
-     */
-    protected $_taxCustomerFactory;
-
-    /**
-     * @param \Magento\Tax\Model\TaxClass\Source\CustomerFactory $taxCustomerFactory
-     */
-    public function __construct(\Magento\Tax\Model\TaxClass\Source\CustomerFactory $taxCustomerFactory)
-    {
-        $this->_taxCustomreFactory = $taxCustomerFactory;
-    }
-
-    /**
-     * Retrieve a list of customer tax classes
-     *
-     * @return array
-     */
-    public function toOptionArray()
-    {
-        /** @var $classCustomer \Magento\Tax\Model\TaxClass\Source\Customer */
-        $classCustomer = $this->_taxCustomreFactory->create();
-        $taxClasses = $classCustomer->toOptionArray();
-        array_unshift($taxClasses, array('value' => '0', 'label' => __('None')));
-        return $taxClasses;
-    }
-}
diff --git a/app/code/Magento/Tax/Model/Observer.php b/app/code/Magento/Tax/Model/Observer.php
index 8a9e2e474bef6c6c28aee22f81d165ad20dc88f5..494460f693dd9bbbd5a4c701c2c738367775d753 100644
--- a/app/code/Magento/Tax/Model/Observer.php
+++ b/app/code/Magento/Tax/Model/Observer.php
@@ -178,17 +178,20 @@ class Observer
                     $baseRealAmount = $row['base_amount'] / $row['percent'] * $tax['percent'];
                 }
                 $hidden = isset($row['hidden']) ? $row['hidden'] : 0;
+                $priority = isset($tax['priority']) ? $tax['priority'] : 0;
+                $position = isset($tax['position']) ? $tax['position'] : 0;
+                $process = isset($row['process']) ? $row['process'] : 0;
                 $data = array(
                     'order_id' => $order->getId(),
                     'code' => $tax['code'],
                     'title' => $tax['title'],
                     'hidden' => $hidden,
                     'percent' => $tax['percent'],
-                    'priority' => $tax['priority'],
-                    'position' => $tax['position'],
+                    'priority' => $priority,
+                    'position' => $position,
                     'amount' => $row['amount'],
                     'base_amount' => $row['base_amount'],
-                    'process' => $row['process'],
+                    'process' => $process,
                     'base_real_amount' => $baseRealAmount
                 );
 
@@ -219,37 +222,6 @@ class Observer
         $order->setAppliedTaxIsSaved(true);
     }
 
-    /**
-     * Add tax percent values to product collection items
-     *
-     * @param   \Magento\Framework\Event\Observer $observer
-     * @return  $this
-     */
-    public function addTaxPercentToProductCollection($observer)
-    {
-        $helper = $this->_taxData;
-        $collection = $observer->getEvent()->getCollection();
-        $store = $collection->getStoreId();
-        if (!$helper->needPriceConversion($store)) {
-            return $this;
-        }
-
-        if ($collection->requireTaxPercent()) {
-            $request = $this->_calculation->getRateRequest();
-            foreach ($collection as $item) {
-                if (null === $item->getTaxClassId()) {
-                    $item->setTaxClassId($item->getMinimalTaxClassId());
-                }
-                if (!isset($classToRate[$item->getTaxClassId()])) {
-                    $request->setProductClassId($item->getTaxClassId());
-                    $classToRate[$item->getTaxClassId()] = $this->_calculation->getRate($request);
-                }
-                $item->setTaxPercent($classToRate[$item->getTaxClassId()]);
-            }
-        }
-        return $this;
-    }
-
     /**
      * Refresh sales tax report statistics for last day
      *
diff --git a/app/code/Magento/Tax/Model/Rate/Source.php b/app/code/Magento/Tax/Model/Rate/Source.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2d3501db1d2c0508e9541690b3e2373d13c3c9c
--- /dev/null
+++ b/app/code/Magento/Tax/Model/Rate/Source.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model\Rate;
+
+use Magento\Tax\Service\V1\TaxRateServiceInterface;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Framework\Convert\Object as Converter;
+use Magento\Tax\Service\V1\Data\TaxRate;
+
+/**
+ * Tax rate source model.
+ */
+class Source implements \Magento\Framework\Data\OptionSourceInterface
+{
+    /** @var array */
+    protected $options;
+
+    /** @var TaxRateServiceInterface */
+    protected $taxRateService;
+
+    /** @var SearchCriteriaBuilder */
+    protected $searchCriteriaBuilder;
+
+    /** @var Converter */
+    protected $converter;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param TaxRateServiceInterface $taxRateService
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param Converter $converter
+     */
+    public function __construct(
+        TaxRateServiceInterface $taxRateService,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        Converter $converter
+    ) {
+        $this->taxRateService = $taxRateService;
+        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+        $this->converter = $converter;
+    }
+
+    /**
+     * Retrieve all tax rates as an options array.
+     *
+     * @return array
+     */
+    public function toOptionArray()
+    {
+        if (!$this->options) {
+            $searchCriteria = $this->searchCriteriaBuilder->create();
+            $searchResults = $this->taxRateService->searchTaxRates($searchCriteria);
+            $this->options = $this->converter->toOptionArray(
+                $searchResults->getItems(),
+                TaxRate::KEY_ID,
+                TaxRate::KEY_CODE
+            );
+        }
+        return $this->options;
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Resource/Calculation/Rule/Collection.php b/app/code/Magento/Tax/Model/Resource/Calculation/Rule/Collection.php
index e9a872c7aca627ac87534100eb4783f82b94f2c3..197db7dba94b3344d864397c6c2114e19ae445ed 100644
--- a/app/code/Magento/Tax/Model/Resource/Calculation/Rule/Collection.php
+++ b/app/code/Magento/Tax/Model/Resource/Calculation/Rule/Collection.php
@@ -40,6 +40,20 @@ class Collection extends \Magento\Framework\Model\Resource\Db\Collection\Abstrac
         $this->_init('Magento\Tax\Model\Calculation\Rule', 'Magento\Tax\Model\Resource\Calculation\Rule');
     }
 
+    /**
+     * Process loaded collection data
+     *
+     * @return $this
+     */
+    protected function _afterLoadData()
+    {
+        parent::_afterLoadData();
+        $this->addCustomerTaxClassesToResult();
+        $this->addProductTaxClassesToResult();
+        $this->addRatesToResult();
+        return $this;
+    }
+
     /**
      * Join calculation data to result
      *
diff --git a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Collection.php b/app/code/Magento/Tax/Model/Resource/Rule/Grid/Collection.php
deleted file mode 100644
index ecf0c2ddb5bfb3176f3935f5a9c232aeed528562..0000000000000000000000000000000000000000
--- a/app/code/Magento/Tax/Model/Resource/Rule/Grid/Collection.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-/**
- * Tax Rule collection
- *
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Tax\Model\Resource\Rule\Grid;
-
-class Collection extends \Magento\Tax\Model\Resource\Calculation\Rule\Collection
-{
-    /**
-     * Process loaded collection data
-     *
-     * @return $this
-     */
-    protected function _afterLoadData()
-    {
-        parent::_afterLoadData();
-        $this->addCustomerTaxClassesToResult();
-        $this->addProductTaxClassesToResult();
-        $this->addRatesToResult();
-
-        return $this;
-    }
-
-    /**
-     * @param string|array $field
-     * @param null|string|array $condition
-     * @return $this
-     */
-    public function addFieldToFilter($field, $condition = null)
-    {
-        switch ($field) {
-            case 'rate.tax_calculation_rate_id':
-                $this->joinCalculationData('rate');
-                break;
-
-            case 'ctc.customer_tax_class_id':
-                $this->joinCalculationData('ctc');
-                break;
-
-            case 'ptc.product_tax_class_id':
-                $this->joinCalculationData('ptc');
-                break;
-        }
-
-        return parent::addFieldToFilter($field, $condition);
-    }
-}
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
index 7b1d6683e6f4a85579be5fc45ebf53fea14e7b90..cba13d0a9f95d5d3d7736dfa4c90fcc8f7f25e6b 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Shipping.php
@@ -24,189 +24,35 @@
 namespace Magento\Tax\Model\Sales\Total\Quote;
 
 use Magento\Sales\Model\Quote\Address;
+use Magento\Tax\Model\Calculation;
 
-class Shipping extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
+class Shipping extends Tax
 {
     /**
-     * Tax calculation model
-     *
-     * @var \Magento\Tax\Model\Calculation
-     */
-    protected $_calculator = null;
-
-    /**
-     * Tax configuration object
-     *
-     * @var \Magento\Tax\Model\Config
-     */
-    protected $_config = null;
-
-    /**
-     * Tax helper instance
-     *
-     * @var \Magento\Tax\Helper\Data|null
+     * {@inheritdoc}
      */
-    protected $_taxHelper = null;
-
-    /**
-     * Flag which is initialized when collect method is started and catalog prices include tax.
-     * It is used for checking if store tax and customer tax requests are similar
-     *
-     * @var bool
-     */
-    protected $_areTaxRequestsSimilar = false;
-
-    /**
-     * Request which can be used for tax rate calculation
-     *
-     * @var \Magento\Framework\Object
-     */
-    protected $_storeTaxRequest = null;
-
-    /**
-     * Class constructor
-     *
-     * @param \Magento\Tax\Model\Calculation $calculation
-     * @param \Magento\Tax\Model\Config $taxConfig
-     * @param \Magento\Tax\Helper\Data $taxHelper
-     */
-    public function __construct(
-        \Magento\Tax\Model\Calculation $calculation,
-        \Magento\Tax\Model\Config $taxConfig,
-        \Magento\Tax\Helper\Data $taxHelper
-    ) {
-        $this->setCode('shipping');
-        $this->_calculator = $calculation;
-        $this->_config = $taxConfig;
-        $this->_taxHelper = $taxHelper;
+    protected function includeShipping()
+    {
+        return true;
     }
-
     /**
-     * Collect totals information about shipping
+     * Override the behavior in Tax collector to not process extra subtotal amount to avoid double counting
      *
-     * @param   Address $address
-     * @return  $this
+     * @return bool
      */
-    public function collect(Address $address)
+    protected function processExtraSubtotalAmount()
     {
-        parent::collect($address);
-        $calc = $this->_calculator;
-        $store = $address->getQuote()->getStore();
-        $storeTaxRequest = $calc->getRateOriginRequest($store);
-        $addressTaxRequest = $calc->getRateRequest(
-            $address,
-            $address->getQuote()->getBillingAddress(),
-            $address->getQuote()->getCustomerTaxClassId(),
-            $store
-        );
-
-        $shippingTaxClass = $this->_config->getShippingTaxClass($store);
-        $storeTaxRequest->setProductClassId($shippingTaxClass);
-        $addressTaxRequest->setProductClassId($shippingTaxClass);
-
-        $priceIncludesTax = $this->_config->shippingPriceIncludesTax($store);
-        if ($priceIncludesTax) {
-            if ($this->_taxHelper->isCrossBorderTradeEnabled($store)) {
-                $this->_areTaxRequestsSimilar = true;
-            } else {
-                $this->_areTaxRequestsSimilar =
-                    $this->_calculator->compareRequests($storeTaxRequest, $addressTaxRequest);
-            }
-        }
-
-        $shipping = $taxShipping = $address->getShippingAmount();
-        $baseShipping = $baseTaxShipping = $address->getBaseShippingAmount();
-        $rate = $calc->getRate($addressTaxRequest);
-        if ($priceIncludesTax) {
-            if ($this->_areTaxRequestsSimilar) {
-                $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, true, false), $rate, true);
-                $baseTax = $this->_round($calc->calcTaxAmount($baseShipping, $rate, true, false), $rate, true, 'base');
-                $taxShipping = $shipping;
-                $baseTaxShipping = $baseShipping;
-                $shipping = $shipping - $tax;
-                $baseShipping = $baseShipping - $baseTax;
-                $taxable = $taxShipping;
-                $baseTaxable = $baseTaxShipping;
-                $isPriceInclTax = true;
-                $address->setTotalAmount('shipping', $shipping);
-                $address->setBaseTotalAmount('shipping', $baseShipping);
-            } else {
-                $storeRate = $calc->getStoreRate($addressTaxRequest, $store);
-                $storeTax = $calc->calcTaxAmount($shipping, $storeRate, true, false);
-                $baseStoreTax = $calc->calcTaxAmount($baseShipping, $storeRate, true, false);
-                $shipping = $calc->round($shipping - $storeTax);
-                $baseShipping = $calc->round($baseShipping - $baseStoreTax);
-                $tax = $this->_round($calc->calcTaxAmount($shipping, $rate, false, false), $rate, true);
-                $baseTax = $this->_round(
-                    $calc->calcTaxAmount($baseShipping, $rate, false, false),
-                    $rate,
-                    true,
-                    'base'
-                );
-                $taxShipping = $shipping + $tax;
-                $baseTaxShipping = $baseShipping + $baseTax;
-                $taxable = $taxShipping;
-                $baseTaxable = $baseTaxShipping;
-                $isPriceInclTax = true;
-                $address->setTotalAmount('shipping', $shipping);
-                $address->setBaseTotalAmount('shipping', $baseShipping);
-            }
-        } else {
-            $appliedRates = $calc->getAppliedRates($addressTaxRequest);
-            $taxes = array();
-            $baseTaxes = array();
-            foreach ($appliedRates as $appliedRate) {
-                $taxRate = $appliedRate['percent'];
-                $taxId = $appliedRate['id'];
-                $taxes[] = $this->_round($calc->calcTaxAmount($shipping, $taxRate, false, false), $taxId, false);
-                $baseTaxes[] = $this->_round(
-                    $calc->calcTaxAmount($baseShipping, $taxRate, false, false),
-                    $taxId,
-                    false,
-                    'base'
-                );
-            }
-            $tax = array_sum($taxes);
-            $baseTax = array_sum($baseTaxes);
-            $taxShipping = $shipping + $tax;
-            $baseTaxShipping = $baseShipping + $baseTax;
-            $taxable = $shipping;
-            $baseTaxable = $baseShipping;
-            $isPriceInclTax = false;
-            $address->setTotalAmount('shipping', $shipping);
-            $address->setBaseTotalAmount('shipping', $baseShipping);
-        }
-        $address->setShippingInclTax($taxShipping);
-        $address->setBaseShippingInclTax($baseTaxShipping);
-        $address->setShippingTaxable($taxable);
-        $address->setBaseShippingTaxable($baseTaxable);
-        $address->setIsShippingInclTax($isPriceInclTax);
-        if ($this->_config->discountTax($store)) {
-            $address->setShippingAmountForDiscount($taxShipping);
-            $address->setBaseShippingAmountForDiscount($baseTaxShipping);
-        }
-        return $this;
+        return false;
     }
 
     /**
-     * Round price based on tax rounding settings
+     * Override the behavior in Tax collector to return empty array
      *
-     * @param float $price
-     * @param string $rate
-     * @param bool $direction
-     * @param string $type
-     * @return float
+     * @param Address $address
+     * @return array
      */
-    protected function _round($price, $rate, $direction, $type = 'regular')
+    public function fetch(Address $address)
     {
-        if (!$price) {
-            return $this->_calculator->round($price);
-        }
-
-        $deltas = $this->_address->getRoundingDeltas();
-        $key = $type . $direction;
-        $rate = (string)$rate;
-        $delta = isset($deltas[$key][$rate]) ? $deltas[$key][$rate] : 0;
-        return $this->_calculator->round($price + $delta);
+        return [];
     }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
index c3a32e2eec2f467890de667ca3cff2dbadafd5dc..80eae0d9f88964c02d7a363a9b312efbc90f19a9 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Subtotal.php
@@ -31,768 +31,37 @@ use Magento\Sales\Model\Quote\Address;
 use Magento\Sales\Model\Quote\Item\AbstractItem;
 use Magento\Tax\Model\Calculation;
 
-class Subtotal extends \Magento\Sales\Model\Quote\Address\Total\AbstractTotal
+class Subtotal extends Tax
 {
     /**
-     * Tax calculation model
-     *
-     * @var \Magento\Tax\Model\Calculation
-     */
-    protected $_calculator = null;
-
-    /**
-     * Tax configuration object
-     *
-     * @var \Magento\Tax\Model\Config
-     */
-    protected $_config = null;
-
-    /**
-     * Tax helper
-     *
-     * @var \Magento\Tax\Helper\Data|null
-     */
-    protected $_helper = null;
-
-    /**
-     * Flag which is initialized when collect method is started and catalog prices include tax.
-     * Is used for checking if store tax and customer tax requests are similar
-     *
-     * @var bool
-     */
-    protected $_areTaxRequestsSimilar = false;
-
-    /**
-     * Request which can be used for tax rate calculation
-     *
-     * @var \Magento\Framework\Object
-     */
-    protected $_storeTaxRequest = null;
-
-    /**
-     *  Quote store
-     *
-     * @var \Magento\Store\Model\Store
-     */
-    protected $_store;
-
-    /**
-     * Rounding deltas for prices
-     *
-     * @var array
-     */
-    protected $_roundingDeltas = array();
-
-    /**
-     * Class constructor
-     *
-     * @param \Magento\Tax\Helper\Data $taxData
-     * @param \Magento\Tax\Model\Calculation $calculation
-     * @param \Magento\Tax\Model\Config $taxConfig
+     * {@inheritdoc}
      */
-    public function __construct(
-        \Magento\Tax\Helper\Data $taxData,
-        \Magento\Tax\Model\Calculation $calculation,
-        \Magento\Tax\Model\Config $taxConfig
-    ) {
-        $this->setCode('tax_subtotal');
-        $this->_helper = $taxData;
-        $this->_calculator = $calculation;
-        $this->_config = $taxConfig;
-    }
-
-    /**
-     * Calculate item price including/excluding tax, row total including/excluding tax
-     * and subtotal including/excluding tax.
-     * Determine discount price if needed
-     *
-     * @param   Address $address
-     * @return  $this
-     */
-    public function collect(Address $address)
+    protected function includeShipping()
     {
-        $this->_store = $address->getQuote()->getStore();
-        $this->_address = $address;
-
-        $this->_roundingDeltas = array();
-
-        $address->setSubtotalInclTax(0);
-        $address->setBaseSubtotalInclTax(0);
-        $address->setTotalAmount('subtotal', 0);
-        $address->setBaseTotalAmount('subtotal', 0);
-
-        $items = $this->_getAddressItems($address);
-        if (!$items) {
-            return $this;
-        }
-
-        $this->_calculator->setCustomerData($address->getQuote()->getCustomerData());
-
-        $addressRequest = $this->_getAddressTaxRequest($address);
-        $storeRequest = $this->_getStoreTaxRequest($address);
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            $classIds = array();
-            foreach ($items as $item) {
-                $classIds[] = $item->getProduct()->getTaxClassId();
-                if ($item->getHasChildren()) {
-                    foreach ($item->getChildren() as $child) {
-                        $classIds[] = $child->getProduct()->getTaxClassId();
-                    }
-                }
-            }
-            $classIds = array_unique($classIds);
-            $storeRequest->setProductClassId($classIds);
-            $addressRequest->setProductClassId($classIds);
-            if ($this->_helper->isCrossBorderTradeEnabled($this->_store)) {
-                $this->_areTaxRequestsSimilar = true;
-            } else {
-                $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests($storeRequest, $addressRequest);
-            }
-        }
-
-        foreach ($items as $item) {
-            if ($item->getParentItem()) {
-                continue;
-            }
-            if ($item->getHasChildren() && $item->isChildrenCalculated()) {
-                foreach ($item->getChildren() as $child) {
-                    $this->_processItem($child, $addressRequest);
-                }
-                $this->_recalculateParent($item);
-            } else {
-                $this->_processItem($item, $addressRequest);
-            }
-            $this->_addSubtotalAmount($address, $item);
-        }
-        $address->setRoundingDeltas($this->_roundingDeltas);
-        return $this;
+        return false;
     }
 
-    /**
-     * Calculate item price and row total with customized rounding level
-     *
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $taxRequest
-     * @return $this
-     */
-    protected function _processItem($item, $taxRequest)
-    {
-        switch ($this->_config->getAlgorithm($this->_store)) {
-            case Calculation::CALC_UNIT_BASE:
-                $this->_unitBaseCalculation($item, $taxRequest);
-                break;
-            case Calculation::CALC_ROW_BASE:
-                $this->_rowBaseCalculation($item, $taxRequest);
-                break;
-            case Calculation::CALC_TOTAL_BASE:
-                $this->_totalBaseCalculation($item, $taxRequest);
-                break;
-            default:
-                break;
-        }
-        return $this;
-    }
 
     /**
-     * Calculate item price and row total including/excluding tax based on unit price rounding level
+     * Override the behavior in Tax collector to not process extra subtotal amount to avoid double counting
      *
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $request
-     * @return $this
-     */
-    protected function _unitBaseCalculation($item, $request)
-    {
-        $request->setProductClassId($item->getProduct()->getTaxClassId());
-        $rate = $this->_calculator->getRate($request);
-        $qty = $item->getTotalQty();
-
-        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
-        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
-        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
-        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
-
-        // if we have a custom price, determine if tax should be based on the original price
-        $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
-        if ($taxOnOrigPrice) {
-            $origPrice = $item->getOriginalPrice();
-            $baseOrigPrice = $item->getBaseOriginalPrice();
-        }
-
-        $item->setTaxPercent($rate);
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            if ($this->_sameRateAsStore($request)) {
-                // determine which price to use when we calculate the tax
-                if ($taxOnOrigPrice) {
-                    $taxable        = $origPrice;
-                    $baseTaxable    = $baseOrigPrice;
-                } else {
-                    $taxable        = $price;
-                    $baseTaxable    = $basePrice;
-                }
-                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true);
-                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true);
-                $taxPrice        = $price;
-                $baseTaxPrice    = $basePrice;
-                $taxSubtotal     = $subtotal;
-                $baseTaxSubtotal = $baseSubtotal;
-                $price = $price - $tax;
-                $basePrice = $basePrice - $baseTax;
-                $subtotal = $price * $qty;
-                $baseSubtotal = $basePrice * $qty;
-                $isPriceInclTax  = true;
-
-                $item->setRowTax($tax * $qty);
-                $item->setBaseRowTax($baseTax * $qty);
-            } else {
-                $storeRate       = $this->_calculator->getStoreRate($request, $this->_store);
-                if ($taxOnOrigPrice) {
-                    // the merchant already provided a customer's price that includes tax
-                    $taxPrice     = $price;
-                    $baseTaxPrice = $basePrice;
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $this->_calculatePriceInclTax($origPrice, $storeRate, $rate);
-                    $baseTaxable  = $this->_calculatePriceInclTax($baseOrigPrice, $storeRate, $rate);
-                } else {
-                    // determine the customer's price that includes tax
-                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
-                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $taxPrice;
-                    $baseTaxable  = $baseTaxPrice;
-                }
-                // determine the customer's tax amount
-                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
-                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
-                // determine the customer's price without taxes
-                $price = $taxPrice - $tax;
-                $basePrice = $baseTaxPrice - $baseTax;
-                // determine subtotal amounts
-                $taxSubtotal = $taxPrice * $qty;
-                $baseTaxSubtotal = $baseTaxPrice * $qty;
-                $subtotal = $price * $qty;
-                $baseSubtotal = $basePrice * $qty;
-                $isPriceInclTax  = true;
-
-                $item->setRowTax($tax * $qty);
-                $item->setBaseRowTax($baseTax * $qty);
-            }
-        } else {
-            // determine which price to use when we calculate the tax
-            if ($taxOnOrigPrice) {
-                $taxable = $origPrice;
-                $baseTaxable = $baseOrigPrice;
-            } else {
-                $taxable = $price;
-                $baseTaxable = $basePrice;
-            }
-            $appliedRates = $this->_calculator->getAppliedRates($request);
-            $taxes = array();
-            $baseTaxes = array();
-            foreach ($appliedRates as $appliedRate) {
-                $taxRate = $appliedRate['percent'];
-                $taxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false);
-                $baseTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false);
-            }
-            $tax             = array_sum($taxes);
-            $baseTax         = array_sum($baseTaxes);
-            $taxPrice        = $price + $tax;
-            $baseTaxPrice    = $basePrice + $baseTax;
-            $taxSubtotal     = $taxPrice * $qty;
-            $baseTaxSubtotal = $baseTaxPrice * $qty;
-            $isPriceInclTax  = false;
-        }
-
-        if ($item->hasCustomPrice()) {
-            /**
-             * Initialize item original price before declaring custom price
-             */
-            $item->getOriginalPrice();
-            $item->setCustomPrice($price);
-            $item->setBaseCustomPrice($basePrice);
-        }
-        $item->setPrice($basePrice);
-        $item->setBasePrice($basePrice);
-        $item->setRowTotal($subtotal);
-        $item->setBaseRowTotal($baseSubtotal);
-        $item->setPriceInclTax($taxPrice);
-        $item->setBasePriceInclTax($baseTaxPrice);
-        $item->setRowTotalInclTax($taxSubtotal);
-        $item->setBaseRowTotalInclTax($baseTaxSubtotal);
-        $item->setTaxableAmount($taxable);
-        $item->setBaseTaxableAmount($baseTaxable);
-        $item->setIsPriceInclTax($isPriceInclTax);
-        if ($this->_config->discountTax($this->_store)) {
-            $item->setDiscountCalculationPrice($taxPrice);
-            $item->setBaseDiscountCalculationPrice($baseTaxPrice);
-        }
-        return $this;
-    }
-
-    /**
-     * Calculate item price and row total including/excluding tax based on row total price rounding level
-     *
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $request
-     * @return $this
-     */
-    protected function _rowBaseCalculation($item, $request)
-    {
-        $request->setProductClassId($item->getProduct()->getTaxClassId());
-        $rate = $this->_calculator->getRate($request);
-        $qty = $item->getTotalQty();
-
-        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
-        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
-        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
-        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
-
-        // if we have a custom price, determine if tax should be based on the original price
-        $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
-        if ($taxOnOrigPrice) {
-            $origSubtotal = $item->getOriginalPrice() * $qty;
-            $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty;
-        }
-
-        $item->setTaxPercent($rate);
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            if ($this->_sameRateAsStore($request)) {
-                // determine which price to use when we calculate the tax
-                if ($taxOnOrigPrice) {
-                    $taxable        = $origSubtotal;
-                    $baseTaxable    = $baseOrigSubtotal;
-                } else {
-                    $taxable        = $taxSubtotal;
-                    $baseTaxable    = $baseTaxSubtotal;
-                }
-                $rowTax          = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
-                $baseRowTax      = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
-                $taxPrice        = $price;
-                $baseTaxPrice    = $basePrice;
-                $taxSubtotal     = $subtotal;
-                $baseTaxSubtotal = $baseSubtotal;
-                $subtotal = $this->_calculator->round($subtotal - $rowTax);
-                $baseSubtotal = $this->_calculator->round($baseSubtotal - $baseRowTax);
-                $price = $this->_calculator->round($subtotal / $qty);
-                $basePrice = $this->_calculator->round($baseSubtotal / $qty);
-                $isPriceInclTax  = true;
-
-                $item->setRowTax($rowTax);
-                $item->setBaseRowTax($baseRowTax);
-            } else {
-                $storeRate       = $this->_calculator->getStoreRate($request, $this->_store);
-                if ($taxOnOrigPrice) {
-                    // the merchant already provided a customer's price that includes tax
-                    $taxPrice     = $price;
-                    $baseTaxPrice = $basePrice;
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate);
-                    $baseTaxable  = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate);
-                } else {
-                    // determine the customer's price that includes tax
-                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
-                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $taxPrice;
-                    $baseTaxable  = $baseTaxPrice;
-                }
-                // determine the customer's tax amount
-                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
-                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
-                // determine the customer's price without taxes
-                $price = $taxPrice - $tax;
-                $basePrice = $baseTaxPrice - $baseTax;
-                // determine subtotal amounts
-                $taxable        *= $qty;
-                $baseTaxable    *= $qty;
-                $taxSubtotal     = $taxPrice * $qty;
-                $baseTaxSubtotal = $baseTaxPrice * $qty;
-                $rowTax          = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
-                $baseRowTax      = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
-                $subtotal        = $taxSubtotal - $rowTax;
-                $baseSubtotal    = $baseTaxSubtotal - $baseRowTax;
-                $isPriceInclTax  = true;
-
-                $item->setRowTax($rowTax);
-                $item->setBaseRowTax($baseRowTax);
-            }
-        } else {
-            // determine which price to use when we calculate the tax
-            if ($taxOnOrigPrice) {
-                $taxable = $origSubtotal;
-                $baseTaxable = $baseOrigSubtotal;
-            } else {
-                $taxable = $subtotal;
-                $baseTaxable = $baseSubtotal;
-            }
-
-            $appliedRates = $this->_calculator->getAppliedRates($request);
-            $rowTaxes = array();
-            $baseRowTaxes = array();
-            foreach ($appliedRates as $appliedRate) {
-                $taxRate = $appliedRate['percent'];
-                $rowTaxes[] = $this->_calculator->calcTaxAmount($taxable, $taxRate, false, true);
-                $baseRowTaxes[] = $this->_calculator->calcTaxAmount($baseTaxable, $taxRate, false, true);
-            }
-            $rowTax          = array_sum($rowTaxes);
-            $baseRowTax      = array_sum($baseRowTaxes);
-            $taxSubtotal     = $subtotal + $rowTax;
-            $baseTaxSubtotal = $baseSubtotal + $baseRowTax;
-            $taxPrice        = $this->_calculator->round($taxSubtotal/$qty);
-            $baseTaxPrice    = $this->_calculator->round($baseTaxSubtotal/$qty);
-            $isPriceInclTax  = false;
-        }
-
-        if ($item->hasCustomPrice()) {
-            /**
-             * Initialize item original price before declaring custom price
-             */
-            $item->getOriginalPrice();
-            $item->setCustomPrice($price);
-            $item->setBaseCustomPrice($basePrice);
-        }
-        $item->setPrice($basePrice);
-        $item->setBasePrice($basePrice);
-        $item->setRowTotal($subtotal);
-        $item->setBaseRowTotal($baseSubtotal);
-        $item->setPriceInclTax($taxPrice);
-        $item->setBasePriceInclTax($baseTaxPrice);
-        $item->setRowTotalInclTax($taxSubtotal);
-        $item->setBaseRowTotalInclTax($baseTaxSubtotal);
-        $item->setTaxableAmount($taxable);
-        $item->setBaseTaxableAmount($baseTaxable);
-        $item->setIsPriceInclTax($isPriceInclTax);
-        if ($this->_config->discountTax($this->_store)) {
-            $item->setDiscountCalculationPrice($taxSubtotal / $qty);
-            $item->setBaseDiscountCalculationPrice($baseTaxSubtotal / $qty);
-        } elseif ($isPriceInclTax) {
-            $item->setDiscountCalculationPrice($subtotal / $qty);
-            $item->setBaseDiscountCalculationPrice($baseSubtotal / $qty);
-        }
-
-        return $this;
-    }
-
-    /**
-     * Calculate item price and row total including/excluding tax based on total price rounding level
-     *
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $request
-     * @return $this
-     */
-    protected function _totalBaseCalculation($item, $request)
-    {
-        $calc = $this->_calculator;
-        $request->setProductClassId($item->getProduct()->getTaxClassId());
-        $rate = $calc->getRate($request);
-        $qty = $item->getTotalQty();
-
-        $price = $taxPrice = $this->_calculator->round($item->getCalculationPriceOriginal());
-        $basePrice = $baseTaxPrice = $this->_calculator->round($item->getBaseCalculationPriceOriginal());
-        $subtotal = $taxSubtotal = $this->_calculator->round($item->getRowTotal());
-        $baseSubtotal = $baseTaxSubtotal = $this->_calculator->round($item->getBaseRowTotal());
-
-        // if we have a custom price, determine if tax should be based on the original price
-        $taxOnOrigPrice = !$this->_helper->applyTaxOnCustomPrice($this->_store) && $item->hasCustomPrice();
-        if ($taxOnOrigPrice) {
-            $origSubtotal = $item->getOriginalPrice() * $qty;
-            $baseOrigSubtotal = $item->getBaseOriginalPrice() * $qty;
-        }
-
-        $item->setTaxPercent($rate);
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            if ($this->_sameRateAsStore($request)) {
-                // determine which price to use when we calculate the tax
-                if ($taxOnOrigPrice) {
-                    $taxable = $origSubtotal;
-                    $baseTaxable = $baseOrigSubtotal;
-                } else {
-                    $taxable = $subtotal;
-                    $baseTaxable = $baseSubtotal;
-                }
-                $rowTaxExact     = $calc->calcTaxAmount($taxable, $rate, true, false);
-                $rowTax          = $this->_deltaRound($rowTaxExact, $rate, true);
-                $baseRowTaxExact = $calc->calcTaxAmount($baseTaxable, $rate, true, false);
-                $baseRowTax      = $this->_deltaRound($baseRowTaxExact, $rate, true, 'base');
-
-                $taxPrice        = $price;
-                $baseTaxPrice    = $basePrice;
-                $taxSubtotal = $subtotal;
-                $baseTaxSubtotal = $baseSubtotal;
-
-                $subtotal          = $subtotal - $rowTax;
-                $baseSubtotal      = $baseSubtotal - $baseRowTax;
-
-                $price = $calc->round($subtotal / $qty);
-                $basePrice = $calc->round($baseSubtotal / $qty);
-
-                $isPriceInclTax  = true;
-
-                //Save the tax calculated
-                $item->setRowTax($rowTax);
-                $item->setBaseRowTax($baseRowTax);
-            } else {
-                $storeRate = $calc->getStoreRate($request, $this->_store);
-                if ($taxOnOrigPrice) {
-                    // the merchant already provided a customer's price that includes tax
-                    $taxPrice     = $price;
-                    $baseTaxPrice = $basePrice;
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $this->_calculatePriceInclTax($item->getOriginalPrice(), $storeRate, $rate);
-                    $baseTaxable  = $this->_calculatePriceInclTax($item->getBaseOriginalPrice(), $storeRate, $rate);
-                } else {
-                    // determine the customer's price that includes tax
-                    $taxPrice     = $this->_calculatePriceInclTax($price, $storeRate, $rate);
-                    $baseTaxPrice = $this->_calculatePriceInclTax($basePrice, $storeRate, $rate);
-                    // determine which price to use when we calculate the tax
-                    $taxable      = $taxPrice;
-                    $baseTaxable  = $baseTaxPrice;
-                }
-                // determine the customer's tax amount based on the taxable price
-                $tax             = $this->_calculator->calcTaxAmount($taxable, $rate, true, true);
-                $baseTax         = $this->_calculator->calcTaxAmount($baseTaxable, $rate, true, true);
-                // determine the customer's price without taxes
-                $price = $taxPrice - $tax;
-                $basePrice = $baseTaxPrice - $baseTax;
-                // determine subtotal amounts
-                $taxable        *= $qty;
-                $baseTaxable    *= $qty;
-                $taxSubtotal     = $taxPrice * $qty;
-                $baseTaxSubtotal = $baseTaxPrice * $qty;
-                $rowTax =
-                    $this->_deltaRound($calc->calcTaxAmount($taxable, $rate, true, false), $rate, true);
-                $baseRowTax =
-                    $this->_deltaRound($calc->calcTaxAmount($baseTaxable, $rate, true, false), $rate, true, 'base');
-                $subtotal = $taxSubtotal - $rowTax;
-                $baseSubtotal = $baseTaxSubtotal - $baseRowTax;
-                $isPriceInclTax  = true;
-
-                $item->setRowTax($rowTax);
-                $item->setBaseRowTax($baseRowTax);
-            }
-        } else {
-            // determine which price to use when we calculate the tax
-            if ($taxOnOrigPrice) {
-                $taxable = $origSubtotal;
-                $baseTaxable = $baseOrigSubtotal;
-            } else {
-                $taxable = $subtotal;
-                $baseTaxable = $baseSubtotal;
-            }
-            $appliedRates = $this->_calculator->getAppliedRates($request);
-            $rowTaxes = array();
-            $baseRowTaxes = array();
-            foreach ($appliedRates as $appliedRate) {
-                $taxId = $appliedRate['id'];
-                $taxRate = $appliedRate['percent'];
-                $rowTaxes[] = $this->_deltaRound($calc->calcTaxAmount($taxable, $taxRate, false, false), $taxId, false);
-                $baseRowTaxes[] = $this->_deltaRound(
-                    $calc->calcTaxAmount($baseTaxable, $taxRate, false, false),
-                    $taxId,
-                    false,
-                    'base'
-                );
-
-            }
-
-            $taxSubtotal     = $subtotal + array_sum($rowTaxes);
-            $baseTaxSubtotal = $baseSubtotal + array_sum($baseRowTaxes);
-
-            $taxPrice        = $calc->round($taxSubtotal/$qty);
-            $baseTaxPrice    = $calc->round($baseTaxSubtotal/$qty);
-
-            $isPriceInclTax = false;
-        }
-
-        if ($item->hasCustomPrice()) {
-            /**
-             * Initialize item original price before declaring custom price
-             */
-            $item->getOriginalPrice();
-            $item->setCustomPrice($price);
-            $item->setBaseCustomPrice($basePrice);
-        } else {
-            $item->setConvertedPrice($price);
-        }
-        $item->setPrice($basePrice);
-        $item->setBasePrice($basePrice);
-        $item->setRowTotal($subtotal);
-        $item->setBaseRowTotal($baseSubtotal);
-        $item->setPriceInclTax($taxPrice);
-        $item->setBasePriceInclTax($baseTaxPrice);
-        $item->setRowTotalInclTax($taxSubtotal);
-        $item->setBaseRowTotalInclTax($baseTaxSubtotal);
-        $item->setTaxableAmount($taxable);
-        $item->setBaseTaxableAmount($baseTaxable);
-        $item->setIsPriceInclTax($isPriceInclTax);
-        if ($this->_config->discountTax($this->_store)) {
-            $item->setDiscountCalculationPrice($taxSubtotal / $qty);
-            $item->setBaseDiscountCalculationPrice($baseTaxSubtotal / $qty);
-        } elseif ($isPriceInclTax) {
-            $item->setDiscountCalculationPrice($subtotal / $qty);
-            $item->setBaseDiscountCalculationPrice($baseSubtotal / $qty);
-        }
-        return $this;
-    }
-
-    /**
-     * Given a store price that includes tax at the store rate, this function will back out the store's tax, and add in
-     * the customer's tax.  Returns this new price which is the customer's price including tax.
-     *
-     * @param float $storePriceInclTax
-     * @param float $storeRate
-     * @param float $customerRate
-     *
-     * @return float
-     */
-    protected function _calculatePriceInclTax($storePriceInclTax, $storeRate, $customerRate)
-    {
-        $storeTax = $this->_calculator->calcTaxAmount($storePriceInclTax, $storeRate, true, false);
-        $priceExclTax = $storePriceInclTax - $storeTax;
-        $customerTax = $this->_calculator->calcTaxAmount($priceExclTax, $customerRate, false, false);
-        $customerPriceInclTax = $this->_calculator->round($priceExclTax + $customerTax);
-        return $customerPriceInclTax;
-    }
-
-    /**
-     * Checks whether request for an item has same rate as store one
-     * Used only after collect() started, as far as uses optimized $_areTaxRequestsSimilar property
-     * Used only in case of prices including tax
-     *
-     * @param \Magento\Framework\Object $request
      * @return bool
      */
-    protected function _sameRateAsStore($request)
-    {
-        // Maybe we know that all requests for currently collected items have same rates
-        if ($this->_areTaxRequestsSimilar) {
-            return true;
-        }
-
-        // Check current request individually
-        $rate = $this->_calculator->getRate($request);
-        $storeRate = $this->_calculator->getStoreRate($request, $this->_store);
-        return $rate == $storeRate;
-    }
-
-    /**
-     * Round price based on previous rounding operation delta
-     *
-     * @param float $price
-     * @param string $rate
-     * @param bool $direction
-     * @param string $type
-     * @return float
-     */
-    protected function _deltaRound($price, $rate, $direction, $type = 'regular')
-    {
-        if ($price) {
-            $rate = (string)$rate;
-            $type = $type . $direction;
-            // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
-            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] :0.000001;
-            $price += $delta;
-            $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
-            $price = $this->_calculator->round($price);
-        }
-        return $price;
-    }
-
-    /**
-     * Recalculate row information for item based on children calculation
-     *
-     * @param   AbstractItem $item
-     * @return  $this
-     */
-    protected function _recalculateParent(AbstractItem $item)
-    {
-        $rowTotal = 0;
-        $baseRowTotal = 0;
-        $rowTotalInclTax = 0;
-        $baseRowTotalInclTax = 0;
-        $rowTax = 0;
-        $baseRowTax = 0;
-        $store = $item->getStore();
-        $qty = $item->getQty();
-
-        foreach ($item->getChildren() as $child) {
-            $rowTotal += $child->getRowTotal();
-            $baseRowTotal += $child->getBaseRowTotal();
-            $rowTotalInclTax += $child->getRowTotalInclTax();
-            $baseRowTotalInclTax += $child->getBaseRowTotalInclTax();
-            $rowTax += $child->getRowTax();
-            $baseRowTax += $child->getBaseRowTax();
-        }
-
-        $item->setConvertedPrice($store->roundPrice($rowTotal) / $qty);
-        $item->setPrice($store->roundPrice($baseRowTotal) / $qty);
-        $item->setRowTotal($rowTotal);
-        $item->setBaseRowTotal($baseRowTotal);
-        $item->setPriceInclTax($store->roundPrice($rowTotalInclTax) / $qty);
-        $item->setBasePriceInclTax($store->roundPrice($baseRowTotalInclTax) / $qty);
-        $item->setRowTotalInclTax($rowTotalInclTax);
-        $item->setBaseRowTotalInclTax($baseRowTotalInclTax);
-        $item->setRowTax($rowTax);
-        $item->setBaseRowTax($baseRowTax);
-        return $this;
-    }
-
-    /**
-     * Get request for fetching store tax rate
-     *
-     * @param   Address $address
-     * @return  \Magento\Framework\Object
-     */
-    protected function _getStoreTaxRequest($address)
-    {
-        if (is_null($this->_storeTaxRequest)) {
-            $this->_storeTaxRequest = $this->_calculator->getRateOriginRequest($address->getQuote()->getStore());
-        }
-        return $this->_storeTaxRequest;
-    }
-
-    /**
-     * Get request for fetching address tax rate
-     *
-     * @param   Address $address
-     * @return  \Magento\Framework\Object
-     */
-    protected function _getAddressTaxRequest($address)
+    protected function processExtraSubtotalAmount()
     {
-        $addressTaxRequest = $this->_calculator->getRateRequest(
-            $address,
-            $address->getQuote()->getBillingAddress(),
-            $address->getQuote()->getCustomerTaxClassId(),
-            $address->getQuote()->getStore()
-        );
-        return $addressTaxRequest;
+        $result = false;
+        return $result;
     }
 
     /**
-     * Add row total item amount to subtotal
+     * Override the behavior in Tax collector to return empty array
      *
-     * @param   Address $address
-     * @param   AbstractItem $item
-     * @return  $this
+     * @param Address $address
+     * @return array
      */
-    protected function _addSubtotalAmount(Address $address, $item)
+    public function fetch(Address $address)
     {
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            $subTotal = $item->getRowTotalInclTax() - $item->getRowTax();
-            $baseSubTotal = $item->getBaseRowTotalInclTax() - $item->getBaseRowTax();
-            $address->setTotalAmount('subtotal', $address->getTotalAmount('subtotal') + $subTotal);
-            $address->setBaseTotalAmount('subtotal', $address->getBaseTotalAmount('subtotal') + $baseSubTotal);
-        } else {
-            $address->setTotalAmount(
-                'subtotal',
-                $address->getTotalAmount('subtotal') + $item->getRowTotal()
-            );
-            $address->setBaseTotalAmount(
-                'subtotal',
-                $address->getBaseTotalAmount('subtotal') + $item->getBaseRowTotal()
-            );
-        }
-        $address->setSubtotalInclTax($address->getSubtotalInclTax() + $item->getRowTotalInclTax());
-        $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $item->getBaseRowTotalInclTax());
-        return $this;
+        $result = [];
+        return $result;
     }
 }
diff --git a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
index 722db2818c4c86e0e69cb1eabc962866baa46a48..776f3d03952ecb3264d8fa28b262d9e19fbd3a25 100644
--- a/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
+++ b/app/code/Magento/Tax/Model/Sales/Total/Quote/Tax.php
@@ -26,57 +26,70 @@ namespace Magento\Tax\Model\Sales\Total\Quote;
 use Magento\Store\Model\Store;
 use Magento\Sales\Model\Quote\Address;
 use Magento\Sales\Model\Quote\Address\Total\AbstractTotal;
-use Magento\Sales\Model\Quote\Item\AbstractItem;
 use Magento\Tax\Model\Calculation;
+use Magento\Sales\Model\Quote\Item\AbstractItem;
+use Magento\Customer\Service\V1\Data\AddressBuilder;
+use Magento\Tax\Service\V1\Data\QuoteDetailsBuilder;
+use Magento\Tax\Service\V1\Data\QuoteDetails\ItemBuilder;
+use Magento\Tax\Service\V1\Data\QuoteDetails\Item as ItemDataObject;
+use Magento\Tax\Service\V1\Data\TaxDetails;
 
 /**
  * Tax totals calculation model
  */
 class Tax extends AbstractTotal
 {
+    /**#@+
+     * Constants defined for type of items
+     */
+    const SHIPPING_ITEM_TYPE = 'shipping';
+    const PRODUCT_ITEM_TYPE = 'product';
+    /**#@-*/
+
     /**
-     * Tax module helper
-     *
-     * @var \Magento\Tax\Helper\Data
+     * Constant for shipping item code
      */
-    protected $_taxData;
+    const SHIPPING_ITEM_CODE = 'shipping';
 
     /**
-     * Tax calculation model
+     * Static counter
      *
-     * @var \Magento\Tax\Model\Calculation
+     * @var int
      */
-    protected $_calculator;
+    protected static $counter = 0;
 
     /**
-     * Tax configuration object
+     * Tax module helper
      *
-     * @var \Magento\Tax\Model\Config
+     * @var \Magento\Tax\Helper\Data
      */
-    protected $_config;
+    protected $_taxData;
 
     /**
-     * Flag which is initialized when collect method is start.
-     * Is used for checking if store tax and customer tax requests are similar
+     * Tax configuration object
      *
-     * @var bool
+     * @var \Magento\Tax\Model\Config
      */
-    protected $_areTaxRequestsSimilar = false;
+    protected $_config;
 
     /**
-     * @var array
+     * @var Store
      */
-    protected $_roundingDeltas = array();
+    protected $_store;
 
     /**
-     * @var array
+     * Tax calculation service, the collector will call the service which performs the actual calculation
+     *
+     * @var \Magento\Tax\Service\V1\TaxCalculationService
      */
-    protected $_baseRoundingDeltas = array();
+    protected $taxCalculationService;
 
     /**
-     * @var Store
+     * Builder to create QuoteDetails as input to tax calculation service
+     *
+     * @var \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder
      */
-    protected $_store;
+    protected $quoteDetailsBuilder;
 
     /**
      * Hidden taxes array
@@ -89,17 +102,20 @@ class Tax extends AbstractTotal
      * Class constructor
      *
      * @param \Magento\Tax\Helper\Data $taxData
-     * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Tax\Model\Config $taxConfig
+     * @param \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService
+     * @param \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder
      */
     public function __construct(
         \Magento\Tax\Helper\Data $taxData,
-        \Magento\Tax\Model\Calculation $calculation,
-        \Magento\Tax\Model\Config $taxConfig
+        \Magento\Tax\Model\Config $taxConfig,
+        \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService,
+        \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder
     ) {
         $this->setCode('tax');
         $this->_taxData = $taxData;
-        $this->_calculator = $calculation;
+        $this->taxCalculationService = $taxCalculationService;
+        $this->quoteDetailsBuilder = $quoteDetailsBuilder;
         $this->_config = $taxConfig;
     }
 
@@ -112,1007 +128,435 @@ class Tax extends AbstractTotal
     public function collect(Address $address)
     {
         parent::collect($address);
-        $this->_roundingDeltas = array();
-        $this->_baseRoundingDeltas = array();
-        $this->_hiddenTaxes = array();
-        $address->setShippingTaxAmount(0);
-        $address->setBaseShippingTaxAmount(0);
-
-        $this->_store = $address->getQuote()->getStore();
-        $customerData = $address->getQuote()->getCustomerData();
-        if ($customerData) {
-            $this->_calculator->setCustomerData($address->getQuote()->getCustomerData());
-        }
-
-        if (!$address->getAppliedTaxesReset()) {
-            $address->setAppliedTaxes(array());
-        }
-
         $items = $this->_getAddressItems($address);
-        if (!count($items)) {
+        if (!$items) {
             return $this;
         }
-        $request = $this->_calculator->getRateRequest(
-            $address,
-            $address->getQuote()->getBillingAddress(),
-            $address->getQuote()->getCustomerTaxClassId(),
-            $this->_store
-        );
-
-        if ($this->_config->priceIncludesTax($this->_store)) {
-            if ($this->_taxData->isCrossBorderTradeEnabled($this->_store)) {
-                $this->_areTaxRequestsSimilar = true;
-            } else {
-                $this->_areTaxRequestsSimilar = $this->_calculator->compareRequests(
-                    $this->_calculator->getRateOriginRequest($this->_store),
-                    $request
-                );
-            }
-        }
-
-        switch ($this->_config->getAlgorithm($this->_store)) {
-            case Calculation::CALC_UNIT_BASE:
-                $this->_unitBaseCalculation($address, $request);
-                break;
-            case Calculation::CALC_ROW_BASE:
-                $this->_rowBaseCalculation($address, $request);
-                break;
-            case Calculation::CALC_TOTAL_BASE:
-                $this->_totalBaseCalculation($address, $request);
-                break;
-            default:
-                break;
-        }
+        //Preparation for calling taxCalculationService with base currency
+        $quoteDetails = $this->prepareQuoteDetails($address, true);
 
-        $this->_addAmount($address->getExtraTaxAmount());
-        $this->_addBaseAmount($address->getBaseExtraTaxAmount());
-        $this->_calculateShippingTax($address, $request);
+        $baseTaxDetailsBase = $this->taxCalculationService
+            ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId());
 
-        $this->_processHiddenTaxes();
+        //Preparation for calling taxCalculationService with display currency
+        $quoteDetails = $this->prepareQuoteDetails($address, false);
 
-        return $this;
-    }
+        $taxDetails = $this->taxCalculationService
+            ->calculateTax($quoteDetails, $address->getQuote()->getStore()->getStoreId());
 
-    /**
-     * Process hidden taxes for items and shippings (in accordance with hidden tax type)
-     *
-     * @return void
-     */
-    protected function _processHiddenTaxes()
-    {
-        $this->_getAddress()->setTotalAmount('hidden_tax', 0);
-        $this->_getAddress()->setBaseTotalAmount('hidden_tax', 0);
-        $this->_getAddress()->setTotalAmount('shipping_hidden_tax', 0);
-        $this->_getAddress()->setBaseTotalAmount('shipping_hidden_tax', 0);
-        foreach ($this->_hiddenTaxes as $taxInfoItem) {
-            if (isset($taxInfoItem['item'])) {
-                // Item hidden taxes
-                $item = $taxInfoItem['item'];
-                $hiddenTax = $taxInfoItem['value'];
-                $baseHiddenTax = $taxInfoItem['base_value'];
-                $qty = $taxInfoItem['qty'];
-
-                $item->setHiddenTaxAmount(max(0, $qty * $hiddenTax));
-                $item->setBaseHiddenTaxAmount(max(0, $qty * $baseHiddenTax));
-                $this->_getAddress()->addTotalAmount('hidden_tax', $item->getHiddenTaxAmount());
-                $this->_getAddress()->addBaseTotalAmount('hidden_tax', $item->getBaseHiddenTaxAmount());
-            } else {
-                // Shipping hidden taxes
-                $hiddenTax = $taxInfoItem['value'];
-                $baseHiddenTax = $taxInfoItem['base_value'];
-
-                $this->_getAddress()->setShippingHiddenTaxAmount(max(0, $hiddenTax));
-                $this->_getAddress()->setBaseShippingHiddenTaxAmnt(max(0, $baseHiddenTax));
-                $this->_getAddress()->addTotalAmount('shipping_hidden_tax', $hiddenTax);
-                $this->_getAddress()->addBaseTotalAmount('shipping_hidden_tax', $baseHiddenTax);
-            }
-        }
-    }
 
-    /**
-     * Calculate shipping tax for a single tax rate
-     *
-     * @param Address $address
-     * @param float $rate
-     * @param array $appliedRates
-     * @param string $taxId
-     * @return $this
-     */
-    protected function _calculateShippingTaxByRate(
-        $address,
-        $rate,
-        $appliedRates,
-        $taxId = null
-    ) {
-        $inclTax = $address->getIsShippingInclTax();
-        $shipping = $address->getShippingTaxable();
-        $baseShipping = $address->getBaseShippingTaxable();
-        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
-
-        $hiddenTax = null;
-        $baseHiddenTax = null;
-        switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $tax = $this->_calculator->calcTaxAmount($shipping, $rate, $inclTax, false);
-                $baseTax = $this->_calculator->calcTaxAmount($baseShipping, $rate, $inclTax, false);
-                break;
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
-                $discountAmount = $address->getShippingDiscountAmount();
-                $baseDiscountAmount = $address->getBaseShippingDiscountAmount();
-                $tax = $this->_calculator->calcTaxAmount(
-                    $shipping - $discountAmount,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-                $baseTax = $this->_calculator->calcTaxAmount(
-                    $baseShipping - $baseDiscountAmount,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-                break;
-        }
+        //Populate address and items with tax calculation results
+        $this->updateTaxInfo($address, $taxDetails, $baseTaxDetailsBase);
 
-        if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) {
-            $tax = $this->_deltaRound($tax, $rateKey, $inclTax);
-            $baseTax = $this->_deltaRound($baseTax, $rateKey, $inclTax, 'base');
-            $this->_addAmount(max(0, $tax));
-            $this->_addBaseAmount(max(0, $baseTax));
-        } else {
-            $tax = $this->_calculator->round($tax);
-            $baseTax = $this->_calculator->round($baseTax);
-            $this->_addAmount(max(0, $tax));
-            $this->_addBaseAmount(max(0, $baseTax));
-        }
-
-        if ($inclTax && !empty($discountAmount)) {
-            $taxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                $shipping,
-                $rate,
-                $inclTax,
-                false
+        if ($this->processExtraSubtotalAmount()) {
+            $address->addTotalAmount('tax', $address->getExtraTaxAmount());
+            $address->addBaseTotalAmount('tax', $address->getBaseExtraTaxAmount());
+            $address->addTotalAmount('subtotal', $address->getExtraSubtotalAmount());
+            $address->addBaseTotalAmount('subtotal', $address->getBaseExtraSubtotalAmount());
+            $address->setSubtotalInclTax(
+                $address->getSubtotalInclTax() + $address->getExtraSubtotalAmount() + $address->getExtraTaxAmount()
             );
-            $baseTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                $baseShipping,
-                $rate,
-                $inclTax,
-                false
+            $address->setBaseSubtotalInclTax(
+                $address->getBaseSubtotalInclTax() +
+                $address->getBaseExtraSubtotalAmount() +
+                $address->getBaseExtraTaxAmount()
             );
-            if ($this->_config->getAlgorithm($this->_store) == Calculation::CALC_TOTAL_BASE) {
-                $taxBeforeDiscount = $this->_deltaRound(
-                    $taxBeforeDiscount,
-                    $rateKey,
-                    $inclTax,
-                    'tax_before_discount'
-                );
-                $baseTaxBeforeDiscount = $this->_deltaRound(
-                    $baseTaxBeforeDiscount,
-                    $rateKey,
-                    $inclTax,
-                    'tax_before_discount_base'
-                );
-            } else {
-                $taxBeforeDiscount = $this->_calculator->round($taxBeforeDiscount);
-                $baseTaxBeforeDiscount = $this->_calculator->round($baseTaxBeforeDiscount);
-            }
-            $hiddenTax = max(0, $taxBeforeDiscount - max(0, $tax));
-            $baseHiddenTax = max(0, $baseTaxBeforeDiscount - max(0, $baseTax));
-            $this->_hiddenTaxes[] = array(
-                'rate_key' => $rateKey,
-                'value' => $hiddenTax,
-                'base_value' => $baseHiddenTax,
-                'incl_tax' => $inclTax,
-            );
-        }
-
-        $address->setShippingTaxAmount($address->getShippingTaxAmount() + max(0, $tax));
-        $address->setBaseShippingTaxAmount($address->getBaseShippingTaxAmount() + max(0, $baseTax));
-        $this->_saveAppliedTaxes($address, $appliedRates, $tax, $baseTax, $rate);
-
-        return $this;
-    }
-
-    /**
-     * Tax calculation for shipping price
-     *
-     * @param   Address $address
-     * @param   \Magento\Framework\Object $taxRateRequest
-     * @return  $this
-     */
-    protected function _calculateShippingTax(
-        Address $address,
-        \Magento\Framework\Object $taxRateRequest
-    ) {
-        $taxRateRequest->setProductClassId($this->_config->getShippingTaxClass($this->_store));
-        $rate = $this->_calculator->getRate($taxRateRequest);
-        $inclTax = $address->getIsShippingInclTax();
-
-        $address->setShippingTaxAmount(0);
-        $address->setBaseShippingTaxAmount(0);
-        $address->setShippingHiddenTaxAmount(0);
-        $address->setBaseShippingHiddenTaxAmount(0);
-        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
-        if ($inclTax) {
-            $this->_calculateShippingTaxByRate($address, $rate, $appliedRates);
-        } else {
-            foreach ($appliedRates as $appliedRate) {
-                $taxRate = $appliedRate['percent'];
-                $taxId = $appliedRate['id'];
-                $this->_calculateShippingTaxByRate($address, $taxRate, array($appliedRate), $taxId);
-            }
         }
         return $this;
     }
 
     /**
-     * Initialize tax related fields in item
-     *
-     * @param AbstractItem $item
-     * @param array $appliedRates
-     * @param float $rate
-     * @param bool $isUnitBasedCalculation
-     * @return bool
-     */
-    protected function initializeItemTax(
-        AbstractItem $item,
-        $appliedRates,
-        $rate,
-        $isUnitBasedCalculation = false
-    ) {
-        $item->setTaxAmount(0);
-        $item->setBaseTaxAmount(0);
-        $item->setHiddenTaxAmount(0);
-        $item->setBaseHiddenTaxAmount(0);
-        $item->setTaxPercent($rate);
-        $item->setDiscountTaxCompensation(0);
-        $rowTotalInclTax = $item->getRowTotalInclTax();
-        $recalculateRowTotalInclTax = false;
-        if (!isset($rowTotalInclTax)) {
-            if ($isUnitBasedCalculation) {
-                $qty = $item->getTotalQty();
-                $item->setRowTotalInclTax($this->_store->roundPrice($item->getTaxableAmount() * $qty));
-                $item->setBaseRowTotalInclTax($this->_store->roundPrice($item->getBaseTaxableAmount() * $qty));
-            } else {
-                $item->setRowTotalInclTax($item->getTaxableAmount());
-                $item->setBaseRowTotalInclTax($item->getBaseTaxableAmount());
-            }
-            $recalculateRowTotalInclTax = true;
-        }
-        $item->setTaxRates($appliedRates);
-
-        return $recalculateRowTotalInclTax;
-    }
-
-    /**
+     * Populate QuoteDetails object from Address object
      *
      * @param Address $address
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $taxRateRequest
-     * @param array $itemTaxGroups
-     * @param boolean $catalogPriceInclTax
-     * @return $this
+     * @param bool $useBaseCurrency
+     * @return \Magento\Tax\Service\V1\Data\QuoteDetails
      */
-    protected function _unitBaseProcessItemTax(
-        Address $address,
-        AbstractItem $item,
-        \Magento\Framework\Object $taxRateRequest,
-        &$itemTaxGroups,
-        $catalogPriceInclTax
-    ) {
-        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
-        $rate = $this->_calculator->getRate($taxRateRequest);
-
-        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate, true);
-
-        if ($catalogPriceInclTax) {
-            $this->_calcUnitTaxAmount($item, $rate);
-            $this->_saveAppliedTaxes(
-                $address,
-                $appliedRates,
-                $item->getTaxAmount(),
-                $item->getBaseTaxAmount(),
-                $rate
-            );
-        } else {
-            //need to calculate each tax separately
-            $taxGroups = array();
-            foreach ($appliedRates as $appliedTax) {
-                $taxId = $appliedTax['id'];
-                $taxRate = $appliedTax['percent'];
-                $this->_calcUnitTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
-                $this->_saveAppliedTaxes(
-                    $address,
-                    array($appliedTax),
-                    $taxGroups[$taxId]['tax'],
-                    $taxGroups[$taxId]['base_tax'],
-                    $taxRate
-                );
-            }
-        }
-        if ($rate > 0) {
-            $itemTaxGroups[$item->getId()] = $appliedRates;
+    protected function prepareQuoteDetails(Address $address, $useBaseCurrency)
+    {
+        $items = $this->_getAddressItems($address);
+        if (!count($items)) {
+            return $this->quoteDetailsBuilder->create();
         }
-        $this->_addAmount($item->getTaxAmount());
-        $this->_addBaseAmount($item->getBaseTaxAmount());
-        return $this;
-    }
 
-    /**
-     * Calculate address tax amount based on one unit price and tax amount
-     *
-     * @param Address $address
-     * @param \Magento\Framework\Object $taxRateRequest
-     * @return $this
-     */
-    protected function _unitBaseCalculation(
-        Address $address,
-        \Magento\Framework\Object $taxRateRequest
-    ) {
-        $items = $this->_getAddressItems($address);
-        $itemTaxGroups = array();
-        $store = $address->getQuote()->getStore();
-        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
+        $addressBuilder = $this->quoteDetailsBuilder->getAddressBuilder();
 
+        //Set billing address
+        $this->quoteDetailsBuilder->setBillingAddress(
+            $this->mapAddress($addressBuilder, $address->getQuote()->getBillingAddress())
+        );
+        //Set shipping address
+        $this->quoteDetailsBuilder->setShippingAddress(
+            $this->mapAddress($addressBuilder, $address)
+        );
+        //Set customer tax class
+        $this->quoteDetailsBuilder->setCustomerTaxClassId($address->getQuote()->getCustomerTaxClassId());
+        //Populate with items
+        $priceIncludesTax = $this->_config->priceIncludesTax($this->_store);
+        $itemBuilder = $this->quoteDetailsBuilder->getItemBuilder();
+        $itemDataObjects = [];
         foreach ($items as $item) {
             if ($item->getParentItem()) {
                 continue;
             }
 
             if ($item->getHasChildren() && $item->isChildrenCalculated()) {
+                $parentItemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency);
+                $itemDataObjects[] = $parentItemDataObject;
                 foreach ($item->getChildren() as $child) {
-                    $this->_unitBaseProcessItemTax(
-                        $address,
+                    $childItemDataObject = $this->mapItem(
+                        $itemBuilder,
                         $child,
-                        $taxRateRequest,
-                        $itemTaxGroups,
-                        $catalogPriceInclTax
+                        $priceIncludesTax,
+                        $useBaseCurrency,
+                        $parentItemDataObject->getCode()
                     );
+                    $itemDataObjects[] = $childItemDataObject;
                 }
-                $this->_recalculateParent($item);
             } else {
-                $this->_unitBaseProcessItemTax(
-                    $address,
-                    $item,
-                    $taxRateRequest,
-                    $itemTaxGroups,
-                    $catalogPriceInclTax
-                );
+                $itemDataObject = $this->mapItem($itemBuilder, $item, $priceIncludesTax, $useBaseCurrency);
+                $itemDataObjects[] = $itemDataObject;
             }
         }
-        if ($address->getQuote()->getTaxesForItems()) {
-            $itemTaxGroups += $address->getQuote()->getTaxesForItems();
+
+        if ($this->includeShipping()) {
+            //Add shipping as an item
+            if (!$address->getShippingTaxCalculationAmount() || $address->getShippingTaxCalculationAmount() <= 0) {
+                //Save the original shipping amount because shipping amount will be overridden
+                //with shipping amount excluding tax
+                $address->setShippingTaxCalculationAmount($address->getShippingAmount());
+                $address->setBaseShippingTaxCalculationAmount($address->getBaseShippingAmount());
+            }
+            if ($address->getShippingTaxCalculationAmount() > 0) {
+                $itemBuilder->setType(self::SHIPPING_ITEM_TYPE);
+                $itemBuilder->setCode(self::SHIPPING_ITEM_CODE);
+                $itemBuilder->setQuantity(1);
+                if ($useBaseCurrency) {
+                    $itemBuilder->setUnitPrice($address->getBaseShippingTaxCalculationAmount());
+                } else {
+                    $itemBuilder->setUnitPrice($address->getShippingTaxCalculationAmount());
+                }
+                if ($address->getShippingDiscountAmount()) {
+                    if ($useBaseCurrency) {
+                        $itemBuilder->setDiscountAmount($address->getBaseShippingDiscountAmount());
+                    } else {
+                        $itemBuilder->setDiscountAmount($address->getShippingDiscountAmount());
+                    }
+                }
+                $itemBuilder->setTaxClassId($this->_config->getShippingTaxClass($this->_store));
+                $itemBuilder->setTaxIncluded($this->_config->shippingPriceIncludesTax($this->_store));
+                $itemDataObjects[] = $itemBuilder->create();
+            }
         }
-        $address->getQuote()->setTaxesForItems($itemTaxGroups);
-        return $this;
+        $this->quoteDetailsBuilder->setItems($itemDataObjects);
+
+        $quoteDetails = $this->quoteDetailsBuilder->create();
+        return $quoteDetails;
     }
 
     /**
-     * Calculate unit tax amount based on unit price
+     * Map Address to Address data object
      *
-     * @param   AbstractItem $item
-     * @param   float $rate
-     * @param   array $taxGroups
-     * @param   string $taxId
-     * @param   bool $recalculateRowTotalInclTax
-     * @return  $this
+     * @param AddressBuilder $addressBuilder
+     * @param Address $address
+     * @return \Magento\Customer\Service\V1\Data\Address
      */
-    protected function _calcUnitTaxAmount(
-        AbstractItem $item,
-        $rate,
-        &$taxGroups = null,
-        $taxId = null,
-        $recalculateRowTotalInclTax = false
-    ) {
-        $qty = $item->getTotalQty();
-        $inclTax = $item->getIsPriceInclTax();
-        $price = $item->getTaxableAmount();
-        $basePrice = $item->getBaseTaxableAmount();
-        $extraTaxableAmount =  $item->getExtraTaxableAmount();
-        $baseExtraTaxableAmount =  $item->getBaseExtraTaxableAmount();
-        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
-
-        $unitTaxBeforeDiscount = 0;
-        $baseUnitTaxBeforeDiscount = 0;
-        switch ($this->_config->getCalculationSequence($this->_store)) {
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false);
-                $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false);
-                $unitTaxBeforeDiscount = $unitTax = $this->_calculator->round($unitTaxBeforeDiscount);
-                $baseUnitTaxBeforeDiscount = $baseUnitTax = $this->_calculator->round($baseUnitTaxBeforeDiscount);
-                break;
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
-                $discountAmount = $item->getDiscountAmount() / $qty;
-                $baseDiscountAmount = $item->getBaseDiscountAmount() / $qty;
-
-                $unitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($price, $rate, $inclTax, false);
-                $unitTaxDiscount = $this->_calculator->calcTaxAmount($discountAmount, $rate, $inclTax, false);
-                $unitTax = $this->_calculator->round(max($unitTaxBeforeDiscount - $unitTaxDiscount, 0));
-
-                $baseUnitTaxBeforeDiscount = $this->_calculator->calcTaxAmount($basePrice, $rate, $inclTax, false);
-                $baseUnitTaxDiscount = $this->_calculator->calcTaxAmount($baseDiscountAmount, $rate, $inclTax, false);
-                $baseUnitTax = $this->_calculator->round(max($baseUnitTaxBeforeDiscount - $baseUnitTaxDiscount, 0));
-
-                $unitTax = $this->_calculator->round($unitTax);
-                $baseUnitTax = $this->_calculator->round($baseUnitTax);
-
-                $unitTaxBeforeDiscount = max(0, $this->_calculator->round($unitTaxBeforeDiscount));
-                $baseUnitTaxBeforeDiscount = max(0, $this->_calculator->round($baseUnitTaxBeforeDiscount));
-
-                if ($inclTax && $discountAmount > 0) {
-                    $hiddenTax = $unitTaxBeforeDiscount - $unitTax;
-                    $baseHiddenTax = $baseUnitTaxBeforeDiscount - $baseUnitTax;
-                    $this->_hiddenTaxes[] = array(
-                        'rate_key' => $rateKey,
-                        'qty' => $qty,
-                        'item' => $item,
-                        'value' => $hiddenTax,
-                        'base_value' => $baseHiddenTax,
-                        'incl_tax' => $inclTax
-                    );
-                } elseif ($discountAmount > $price) {
-                    // case with 100% discount on price incl. tax
-                    $hiddenTax = $discountAmount - $price;
-                    $baseHiddenTax = $baseDiscountAmount - $basePrice;
-                    $this->_hiddenTaxes[] = array(
-                        'rate_key' => $rateKey,
-                        'qty' => $qty,
-                        'item' => $item,
-                        'value' => $hiddenTax,
-                        'base_value' => $baseHiddenTax,
-                        'incl_tax' => $inclTax
-                    );
-                }
-                break;
-        }
-        $rowTax = $this->_store->roundPrice(max(0, $qty * $unitTax));
-        $baseRowTax = $this->_store->roundPrice(max(0, $qty * $baseUnitTax));
-
-        $extraTaxAmount = $this->_calculator->calcTaxAmount($extraTaxableAmount, $rate, $inclTax, true);
-        $rowExtraTaxAmount = $extraTaxAmount * $qty;
-        $baseExtraTaxAmount = $this->_calculator->calcTaxAmount($baseExtraTaxableAmount, $rate, $inclTax, true);
-        $rowBaseExtraTaxAmount = $baseExtraTaxAmount * $qty;
-        $rowTax += $rowExtraTaxAmount;
-        $baseRowTax += $rowBaseExtraTaxAmount;
-        $item->setTaxAmount($item->getTaxAmount() + $rowTax);
-        $item->setBaseTaxAmount($item->getBaseTaxAmount() + $baseRowTax);
-        if (is_array($taxGroups)) {
-            $taxGroups[$rateKey]['tax'] = max(0, $rowTax);
-            $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax);
-        }
-
-        $rowTotalInclTax = $item->getRowTotalInclTax();
-        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
-            if ($this->_config->priceIncludesTax($this->_store)) {
-                $item->setRowTotalInclTax($price * $qty);
-                $item->setBaseRowTotalInclTax($basePrice * $qty);
-            } else {
-                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $unitTaxBeforeDiscount * $qty);
-                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseUnitTaxBeforeDiscount * $qty);
-            }
-        }
+    protected function mapAddress(AddressBuilder $addressBuilder, Address $address)
+    {
+        $addressBuilder->setCountryId($address->getCountryId());
+        $addressBuilder->setRegion(
+            $addressBuilder->getRegionBuilder()
+                ->setRegionId($address->getRegionId())
+                ->create()
+        );
+        $addressBuilder->setPostcode($address->getPostcode());
+        $addressBuilder->setCity($address->getCity());
+        $addressBuilder->setStreet($address->getStreet());
 
-        return $this;
+        return $addressBuilder->create();
     }
 
     /**
+     * Map an item to item data object
      *
-     * @param Address $address
+     * @param ItemBuilder $itemBuilder
      * @param AbstractItem $item
-     * @param \Magento\Framework\Object $taxRateRequest
-     * @param array $itemTaxGroups
-     * @param bool $catalogPriceInclTax
-     * @return $this
+     * @param bool $priceIncludesTax
+     * @param bool $useBaseCurrency
+     * @param string $parentCode
+     * @return ItemDataObject
      */
-    protected function _rowBaseProcessItemTax(
-        Address $address,
+    protected function mapItem(
+        ItemBuilder $itemBuilder,
         AbstractItem $item,
-        \Magento\Framework\Object $taxRateRequest,
-        &$itemTaxGroups,
-        $catalogPriceInclTax
+        $priceIncludesTax,
+        $useBaseCurrency,
+        $parentCode = null
     ) {
-        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
-        $rate = $this->_calculator->getRate($taxRateRequest);
+        if (!$item->getSequence()) {
+            $sequence = 'sequence-' . $this->getNextIncrement();
+            $item->setSequence($sequence);
+        }
+        $itemBuilder->setCode($item->getSequence());
+        $itemBuilder->setQuantity($item->getQty());
+        $itemBuilder->setTaxClassId($item->getProduct()->getTaxClassId());
 
-        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate);
+        $itemBuilder->setTaxIncluded($priceIncludesTax);
+        $itemBuilder->setType('product'); //TODO: find a place to define constants
 
-        if ($catalogPriceInclTax) {
-            $this->_calcRowTaxAmount($item, $rate);
-            $this->_saveAppliedTaxes($address, $appliedRates, $item->getTaxAmount(), $item->getBaseTaxAmount(), $rate);
+        if ($item->getParentItem()) {
+            $itemBuilder->setParentCode($item->getParentItem()->getId());
+        }
+
+        if ($useBaseCurrency) {
+            if (!$item->getBaseTaxCalculationPrice()) {
+                $item->setBaseTaxCalculationPrice($item->getBaseCalculationPriceOriginal());
+            }
+            $itemBuilder->setUnitPrice($item->getBaseTaxCalculationPrice());
+            $itemBuilder->setDiscountAmount($item->getBaseDiscountAmount());
         } else {
-            //need to calculate each tax separately
-            $taxGroups = array();
-            foreach ($appliedRates as $appliedTax) {
-                $taxId = $appliedTax['id'];
-                $taxRate = $appliedTax['percent'];
-                $this->_calcRowTaxAmount($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
-                $this->_saveAppliedTaxes(
-                    $address,
-                    array($appliedTax),
-                    $taxGroups[$taxId]['tax'],
-                    $taxGroups[$taxId]['base_tax'],
-                    $taxRate
-                );
+            if (!$item->getTaxCalculationPrice()) {
+                $item->setTaxCalculationPrice($item->getCalculationPriceOriginal());
             }
-
+            $itemBuilder->setUnitPrice($item->getTaxCalculationPrice());
+            $itemBuilder->setDiscountAmount($item->getDiscountAmount());
         }
-        if ($rate > 0) {
-            $itemTaxGroups[$item->getId()] = $appliedRates;
-        }
-        $this->_addAmount($item->getTaxAmount());
-        $this->_addBaseAmount($item->getBaseTaxAmount());
-        return $this;
+
+        $itemBuilder->setParentCode($parentCode);
+
+        return $itemBuilder->create();
     }
 
     /**
-     * Calculate address total tax based on row total
+     * Increment and return static counter
      *
-     * @param   Address $address
-     * @param   \Magento\Framework\Object $taxRateRequest
-     * @return  $this
+     * @return int
      */
-    protected function _rowBaseCalculation(
-        Address $address,
-        \Magento\Framework\Object $taxRateRequest
-    ) {
-        $items = $this->_getAddressItems($address);
-        $itemTaxGroups = array();
-        $store = $address->getQuote()->getStore();
-        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
-
-        foreach ($items as $item) {
-            if ($item->getParentItem()) {
-                continue;
-            }
-            if ($item->getHasChildren() && $item->isChildrenCalculated()) {
-                foreach ($item->getChildren() as $child) {
-                    $this->_rowBaseProcessItemTax(
-                        $address,
-                        $child,
-                        $taxRateRequest,
-                        $itemTaxGroups,
-                        $catalogPriceInclTax
-                    );
-                }
-                $this->_recalculateParent($item);
-            } else {
-                $this->_rowBaseProcessItemTax(
-                    $address,
-                    $item,
-                    $taxRateRequest,
-                    $itemTaxGroups,
-                    $catalogPriceInclTax
-                );
-            }
-        }
-
-        if ($address->getQuote()->getTaxesForItems()) {
-            $itemTaxGroups += $address->getQuote()->getTaxesForItems();
-        }
-        $address->getQuote()->setTaxesForItems($itemTaxGroups);
-        return $this;
+    protected function getNextIncrement()
+    {
+        return ++self::$counter;
     }
 
     /**
-     * Calculate item tax amount based on row total
+     * Update item tax and prices from item tax details object from tax calculation service
      *
-     * @param   AbstractItem $item
-     * @param   float $rate
-     * @param   array $taxGroups
-     * @param   string $taxId
-     * @param   bool $recalculateRowTotalInclTax
-     * @return  $this
+     * @param Address $address
+     * @param TaxDetails $taxDetails
+     * @param TaxDetails $baseTaxDetails
+     * @return $this
      */
-    protected function _calcRowTaxAmount(
-        AbstractItem $item,
-        $rate,
-        &$taxGroups = null,
-        $taxId = null,
-        $recalculateRowTotalInclTax = false
-    ) {
-        $inclTax = $item->getIsPriceInclTax();
-        $subtotal = $taxSubtotal = $item->getTaxableAmount();
-        $baseSubtotal = $baseTaxSubtotal = $item->getBaseTaxableAmount();
-        $extraRowTaxableAmount = $item->getExtraRowTaxableAmount();
-        $baseExtraRowTaxableAmount = $item->getBaseExtraRowTaxableAmount();
-        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
-
-        $hiddenTax = 0;
-        $baseHiddenTax = 0;
-        $rowTaxBeforeDiscount = 0;
-        $baseRowTaxBeforeDiscount = 0;
-
-        switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
-                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false);
-
-                $rowTaxBeforeDiscount = $rowTax = $this->_calculator->round($rowTaxBeforeDiscount);
-                $baseRowTaxBeforeDiscount = $baseRowTax = $this->_calculator->round($baseRowTaxBeforeDiscount);
-                break;
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
-                $discountAmount = $item->getDiscountAmount();
-                $baseDiscountAmount = $item->getBaseDiscountAmount();
-                $rowTax = $this->_calculator->calcTaxAmount(max($subtotal - $discountAmount, 0), $rate, $inclTax);
-                $baseRowTax = $this->_calculator->calcTaxAmount(
-                    max($baseSubtotal - $baseDiscountAmount, 0),
-                    $rate,
-                    $inclTax
-                );
-                $rowTax = $this->_calculator->round($rowTax);
-                $baseRowTax = $this->_calculator->round($baseRowTax);
-
-                //Calculate the Row Tax before discount
-                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                    $subtotal,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                    $baseSubtotal,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-
-                $rowTaxBeforeDiscount = max(0, $this->_calculator->round($rowTaxBeforeDiscount));
-                $baseRowTaxBeforeDiscount = max(0, $this->_calculator->round($baseRowTaxBeforeDiscount));
-
-                if ($inclTax && $discountAmount > 0) {
-                    $hiddenTax = $rowTaxBeforeDiscount - $rowTax;
-                    $baseHiddenTax = $baseRowTaxBeforeDiscount - $baseRowTax;
-                    $this->_hiddenTaxes[] = array(
-                        'rate_key' => $rateKey,
-                        'qty' => 1,
-                        'item' => $item,
-                        'value' => $hiddenTax,
-                        'base_value' => $baseHiddenTax,
-                        'incl_tax' => $inclTax
-                    );
-                } elseif ($discountAmount > $subtotal) {
-                    // case with 100% discount on price incl. tax
-                    $hiddenTax = $discountAmount - $subtotal;
-                    $baseHiddenTax = $baseDiscountAmount - $baseSubtotal;
-                    $this->_hiddenTaxes[] = array(
-                        'rate_key' => $rateKey,
-                        'qty' => 1,
-                        'item' => $item,
-                        'value' => $hiddenTax,
-                        'base_value' => $baseHiddenTax,
-                        'incl_tax' => $inclTax
-                    );
-                }
-                break;
+    protected function updateTaxInfo(Address $address, TaxDetails $taxDetails, TaxDetails $baseTaxDetails)
+    {
+        $address->setAppliedTaxes([]);
+        /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $keyedItems */
+        $keyedItems = [];
+        foreach ($taxDetails->getItems() as $item) {
+            $keyedItems[$item->getCode()] = $item;
         }
-        //round tax on extra taxable separately
-        $rowExtraTaxAmount = $this->_calculator->calcTaxAmount($extraRowTaxableAmount, $rate, $inclTax, true);
-        $baseRowExtraTaxAmount = $this->_calculator->calcTaxAmount($baseExtraRowTaxableAmount, $rate, $inclTax, true);
-        $rowTax += $rowExtraTaxAmount;
-        $baseRowTax += $baseRowExtraTaxAmount;
-
-        $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
-        $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
-        if (is_array($taxGroups)) {
-            $taxGroups[$rateKey]['tax'] = max(0, $rowTax);
-            $taxGroups[$rateKey]['base_tax'] = max(0, $baseRowTax);
+        /** @var \Magento\Tax\Service\V1\Data\TaxDetails\Item[] $baseKeyedItems */
+        $baseKeyedItems = [];
+        foreach ($baseTaxDetails->getItems() as $item) {
+            $baseKeyedItems[$item->getCode()] = $item;
         }
 
-        $rowTotalInclTax = $item->getRowTotalInclTax();
-        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
-            if ($this->_config->priceIncludesTax($this->_store)) {
-                $item->setRowTotalInclTax($subtotal);
-                $item->setBaseRowTotalInclTax($baseSubtotal);
-            } else {
-                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $rowTaxBeforeDiscount);
-                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseRowTaxBeforeDiscount);
-            }
+        $appliedTaxesByItem = [];
+
+        /** @var AbstractItem[] $keyedAddressItems */
+        $keyedAddressItems = [];
+        foreach ($this->_getAddressItems($address) as $addressItem) {
+            $keyedAddressItems[$addressItem->getSequence()] = $addressItem;
         }
-        return $this;
-    }
 
-    /**
-     * Calculate address total tax based on address subtotal
-     *
-     * @param   Address $address
-     * @param   \Magento\Framework\Object $taxRateRequest
-     * @return  $this
-     */
-    protected function _totalBaseCalculation(
-        Address $address,
-        \Magento\Framework\Object $taxRateRequest
-    ) {
-        $items = $this->_getAddressItems($address);
-        $store = $address->getQuote()->getStore();
-        $taxGroups = array();
-        $itemTaxGroups = array();
-        $catalogPriceInclTax = $this->_config->priceIncludesTax($store);
+        $subtotal = $baseSubtotal = 0;
+        $hiddenTax = $baseHiddenTax = 0;
+        $tax = $baseTax = 0;
+        $subtotalInclTax = $baseSubtotalInclTax = 0;
 
-        foreach ($items as $item) {
-            if ($item->getParentItem()) {
-                continue;
-            }
+        foreach ($keyedItems as $code => $itemTaxDetails) {
+            $baseItemTaxDetails = $baseKeyedItems[$code];
+            $type = $itemTaxDetails->getType();
+            if ($type == self::PRODUCT_ITEM_TYPE) {
+                $quoteItem = $keyedAddressItems[$code];
+                $this->updateItemTaxInfo($quoteItem, $itemTaxDetails, $baseItemTaxDetails);
 
-            if ($item->getHasChildren() && $item->isChildrenCalculated()) {
-                foreach ($item->getChildren() as $child) {
-                    $this->_totalBaseProcessItemTax(
-                        $child,
-                        $taxRateRequest,
-                        $taxGroups,
-                        $itemTaxGroups,
-                        $catalogPriceInclTax
+                if ($quoteItem->getHasChildren() && $quoteItem->isChildrenCalculated()) {
+                    //avoid double counting
+                    continue;
+                }
+                $subtotal += $itemTaxDetails->getRowTotal();
+                $baseSubtotal += $baseItemTaxDetails->getRowTotal();
+                $hiddenTax += $itemTaxDetails->getDiscountTaxCompensationAmount();
+                $baseHiddenTax += $baseItemTaxDetails->getDiscountTaxCompensationAmount();
+                $tax += $itemTaxDetails->getRowTax();
+                $baseTax += $baseItemTaxDetails->getRowTax();
+                $subtotalInclTax += $itemTaxDetails->getRowTotalInclTax();
+                $baseSubtotalInclTax += $baseItemTaxDetails->getRowTotalInclTax();
+
+                $appliedTaxes = $itemTaxDetails->getAppliedTaxes();
+                $baseAppliedTaxes = $baseItemTaxDetails->getAppliedTaxes();
+                $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes);
+
+                foreach ($appliedTaxesArray as $appliedTaxArray) {
+                    $this->_saveAppliedTaxes(
+                        $address,
+                        [$appliedTaxArray],
+                        $appliedTaxArray['amount'],
+                        $appliedTaxArray['base_amount'],
+                        $appliedTaxArray['percent']
                     );
                 }
-                $this->_recalculateParent($item);
-            } else {
-                $this->_totalBaseProcessItemTax(
-                    $item,
-                    $taxRateRequest,
-                    $taxGroups,
-                    $itemTaxGroups,
-                    $catalogPriceInclTax
-                );
+
+                $appliedTaxesByItem[$quoteItem->getId()] = $appliedTaxesArray;
+                //Set applied tax for item
+                $quoteItem->setAppliedTaxes($appliedTaxesArray);
             }
+            $address->getQuote()->setTaxesForItems($appliedTaxesByItem);
         }
 
-        if ($address->getQuote()->getTaxesForItems()) {
-            $itemTaxGroups += $address->getQuote()->getTaxesForItems();
-        }
-        $address->getQuote()->setTaxesForItems($itemTaxGroups);
+        // Set item subtotals
+        $address->setTotalAmount('subtotal', $subtotal);
+        $address->setBaseTotalAmount('subtotal', $baseSubtotal);
 
-        foreach ($taxGroups as $taxId => $data) {
-            if ($catalogPriceInclTax) {
-                $rate = (float)$taxId;
-            } else {
-                $rate = $data['applied_rates'][0]['percent'];
-            }
+        $address->setSubtotalInclTax($subtotalInclTax);
+        $address->setBaseSubtotalInclTax($baseSubtotalInclTax);
+        $address->setTotalAmount('hidden_tax', $hiddenTax);
+        $address->setBaseTotalAmount('hidden_tax', $baseHiddenTax);
+
+        //Set shipping tax
+        if (isset($keyedItems[self::SHIPPING_ITEM_CODE]) && isset($baseKeyedItems[self::SHIPPING_ITEM_CODE])) {
+            $shippingItem = $keyedItems[self::SHIPPING_ITEM_CODE];
+            $baseShippingItem = $baseKeyedItems[self::SHIPPING_ITEM_CODE];
+
+            $this->updateShippingTaxInfo($address, $shippingItem, $baseShippingItem);
 
-            $totalTax = array_sum($data['tax']);
-            $baseTotalTax = array_sum($data['base_tax']);
-            $this->_addAmount($totalTax);
-            $this->_addBaseAmount($baseTotalTax);
-            $totalTaxRounded = $this->_calculator->round($totalTax);
-            $baseTotalTaxRounded = $this->_calculator->round($totalTaxRounded);
-            $this->_saveAppliedTaxes($address, $data['applied_rates'], $totalTaxRounded, $baseTotalTaxRounded, $rate);
+            $tax += $shippingItem->getRowTax();
+            $baseTax += $baseShippingItem->getRowTax();
         }
 
+        $address->setTotalAmount('tax', $tax);
+        $address->setBaseTotalAmount('tax', $baseTax);
+
         return $this;
     }
 
     /**
+     * Update tax related fields for quote item
      *
-     * @param AbstractItem $item
-     * @param \Magento\Framework\Object $taxRateRequest
-     * @param array $taxGroups
-     * @param array $itemTaxGroups
-     * @param bool $catalogPriceInclTax
+     * @param AbstractItem $quoteItem
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $itemTaxDetails
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $baseItemTaxDetails
      * @return $this
      */
-    protected function _totalBaseProcessItemTax(
-        AbstractItem $item,
-        \Magento\Framework\Object $taxRateRequest,
-        &$taxGroups,
-        &$itemTaxGroups,
-        $catalogPriceInclTax
-    ) {
-        $taxRateRequest->setProductClassId($item->getProduct()->getTaxClassId());
-        $appliedRates = $this->_calculator->getAppliedRates($taxRateRequest);
-        $rate = $this->_calculator->getRate($taxRateRequest);
-
-        $recalculateRowTotalInclTax = $this->initializeItemTax($item, $appliedRates, $rate);
-
-        if ($catalogPriceInclTax) {
-            $taxGroups[(string)$rate]['applied_rates'] = $appliedRates;
-            $taxGroups[(string)$rate]['incl_tax'] = $item->getIsPriceInclTax();
-            $this->_aggregateTaxPerRate($item, $rate, $taxGroups);
+    protected function updateItemTaxInfo($quoteItem, $itemTaxDetails, $baseItemTaxDetails)
+    {
+        //The price should be base price
+        $quoteItem->setPrice($baseItemTaxDetails->getPrice());
+        $quoteItem->setConvertedPrice($itemTaxDetails->getPrice());
+        $quoteItem->setPriceInclTax($itemTaxDetails->getPriceInclTax());
+        $quoteItem->setRowTotal($itemTaxDetails->getRowTotal());
+        $quoteItem->setRowTotalInclTax($itemTaxDetails->getRowTotalInclTax());
+        $quoteItem->setTaxAmount($itemTaxDetails->getRowTax());
+        $quoteItem->setTaxPercent($itemTaxDetails->getTaxPercent());
+        $quoteItem->setHiddenTaxAmount($itemTaxDetails->getDiscountTaxCompensationAmount());
+
+        $quoteItem->setBasePrice($baseItemTaxDetails->getPrice());
+        $quoteItem->setBasePriceInclTax($baseItemTaxDetails->getPriceInclTax());
+        $quoteItem->setBaseRowTotal($baseItemTaxDetails->getRowTotal());
+        $quoteItem->setBaseRowTotalInclTax($baseItemTaxDetails->getRowTotalInclTax());
+        $quoteItem->setBaseTaxAmount($baseItemTaxDetails->getRowTax());
+        $quoteItem->setTaxPercent($baseItemTaxDetails->getTaxPercent());
+        $quoteItem->setBaseHiddenTaxAmount($baseItemTaxDetails->getDiscountTaxCompensationAmount());
+
+        //Set discount calculation price, this may be needed by discount collector
+        if ($this->_config->discountTax($this->_store)) {
+            $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPriceInclTax());
+            $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPriceInclTax());
         } else {
-            //need to calculate each tax separately
-            foreach ($appliedRates as $appliedTax) {
-                $taxId = $appliedTax['id'];
-                $taxRate = $appliedTax['percent'];
-                $taxGroups[$taxId]['applied_rates'] = array($appliedTax);
-                $taxGroups[$taxId]['incl_tax'] = $item->getIsPriceInclTax();
-                $this->_aggregateTaxPerRate($item, $taxRate, $taxGroups, $taxId, $recalculateRowTotalInclTax);
-            }
-        }
-        if ($rate > 0) {
-            $itemTaxGroups[$item->getId()] = $appliedRates;
+            $quoteItem->setDiscountCalculationPrice($itemTaxDetails->getPrice());
+            $quoteItem->setBaseDiscountCalculationPrice($baseItemTaxDetails->getPrice());
+
         }
         return $this;
     }
 
     /**
-     * Aggregate row totals per tax rate in array
+     * Update tax related fields for shipping
      *
-     * @param   AbstractItem $item
-     * @param   float $rate
-     * @param   array &$taxGroups
-     * @param   string $taxId
-     * @param   bool $recalculateRowTotalInclTax
-     * @return  $this
+     * @param Address $address
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $shippingTaxDetails
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\Item $baseShippingTaxDetails
+     * @return $this
      */
-    protected function _aggregateTaxPerRate(
-        AbstractItem $item,
-        $rate,
-        &$taxGroups,
-        $taxId = null,
-        $recalculateRowTotalInclTax = false
-    ) {
-        $inclTax = $item->getIsPriceInclTax();
-        $rateKey = ($taxId == null) ? (string)$rate : $taxId;
-        $taxSubtotal = $subtotal = $item->getTaxableAmount();
-        $baseTaxSubtotal = $baseSubtotal = $item->getBaseTaxableAmount();
-        $extraTaxableAmount = $item->getExtraRowTaxableAmount();
-        $baseExtraTaxableAmount =  $item->getBaseExtraRowTaxableAmount();
-
-        if (!isset($taxGroups[$rateKey]['totals'])) {
-            $taxGroups[$rateKey]['totals'] = array();
-            $taxGroups[$rateKey]['base_totals'] = array();
-        }
-
-        $hiddenTax = null;
-        $baseHiddenTax = null;
-        $discount = 0;
-        $rowTaxBeforeDiscount = 0;
-        $baseRowTaxBeforeDiscount = 0;
-        switch ($this->_taxData->getCalculationSequence($this->_store)) {
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_BEFORE_DISCOUNT_ON_INCL:
-                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($subtotal, $rate, $inclTax, false);
-                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount($baseSubtotal, $rate, $inclTax, false);
-
-                $taxBeforeDiscountRounded = $rowTax = $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax);
-                $baseTaxBeforeDiscountRounded = $baseRowTax = $this->_deltaRound(
-                    $baseRowTaxBeforeDiscount,
-                    $rateKey,
-                    $inclTax,
-                    'base'
-                );
-
-                //Round extra tax amount separately
-                $extraTaxAmount = $this->_calculator->calcTaxAmount($extraTaxableAmount, $rate, $inclTax, true);
-                $baseExtraTaxAmount = $this->_calculator->calcTaxAmount($baseExtraTaxableAmount, $rate, $inclTax, true);
-                $rowTax += $extraTaxAmount;
-                $baseRowTax += $baseExtraTaxAmount;
-
-                $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
-                $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
-                break;
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_EXCL:
-            case Calculation::CALC_TAX_AFTER_DISCOUNT_ON_INCL:
-                if ($this->_taxData->applyTaxOnOriginalPrice($this->_store)) {
-                    $discount = $item->getOriginalDiscountAmount();
-                    $baseDiscount = $item->getBaseOriginalDiscountAmount();
-                } else {
-                    $discount = $item->getDiscountAmount();
-                    $baseDiscount = $item->getBaseDiscountAmount();
-                }
-
-                $taxSubtotal = max($subtotal - $discount, 0);
-                $baseTaxSubtotal = max($baseSubtotal - $baseDiscount, 0);
-
-                $rowTax = $this->_calculator->calcTaxAmount($taxSubtotal, $rate, $inclTax, false);
-                $baseRowTax = $this->_calculator->calcTaxAmount($baseTaxSubtotal, $rate, $inclTax, false);
-
-                $rowTax = $this->_deltaRound($rowTax, $rateKey, $inclTax);
-                $baseRowTax = $this->_deltaRound($baseRowTax, $rateKey, $inclTax, 'base');
-
-                //Calculate the Row taxes before discount
-                $rowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                    $subtotal,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-                $baseRowTaxBeforeDiscount = $this->_calculator->calcTaxAmount(
-                    $baseSubtotal,
-                    $rate,
-                    $inclTax,
-                    false
-                );
-
-                $taxBeforeDiscountRounded = max(
-                    0,
-                    $this->_deltaRound($rowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount')
-                );
-                $baseTaxBeforeDiscountRounded = max(
-                    0,
-                    $this->_deltaRound($baseRowTaxBeforeDiscount, $rateKey, $inclTax, 'tax_before_discount_base')
-                );
-
-
-                if ($inclTax && $discount > 0) {
-                    $hiddenTax = $taxBeforeDiscountRounded - max(0, $rowTax);
-                    $baseHiddenTax = $baseTaxBeforeDiscountRounded - max(0, $baseRowTax);
-                    $this->_hiddenTaxes[] = array(
-                        'rate_key' => $rateKey,
-                        'qty' => 1,
-                        'item' => $item,
-                        'value' => $hiddenTax,
-                        'base_value' => $baseHiddenTax,
-                        'incl_tax' => $inclTax
-                    );
-                }
-
-                //Round extra tax amount separately
-                $extraTaxAmount = $this->_calculator->calcTaxAmount($extraTaxableAmount, $rate, $inclTax, true);
-                $baseExtraTaxAmount = $this->_calculator->calcTaxAmount($baseExtraTaxableAmount, $rate, $inclTax, true);
-                $rowTax += $extraTaxAmount;
-                $baseRowTax += $baseExtraTaxAmount;
-
-                $item->setTaxAmount($item->getTaxAmount() + max(0, $rowTax));
-                $item->setBaseTaxAmount($item->getBaseTaxAmount() + max(0, $baseRowTax));
-
-                break;
-        }
-
-        $rowTotalInclTax = $item->getRowTotalInclTax();
-        if (!isset($rowTotalInclTax) || $recalculateRowTotalInclTax) {
-            if ($this->_config->priceIncludesTax($this->_store)) {
-                $item->setRowTotalInclTax($subtotal);
-                $item->setBaseRowTotalInclTax($baseSubtotal);
-            } else {
-                $item->setRowTotalInclTax($item->getRowTotalInclTax() + $taxBeforeDiscountRounded);
-                $item->setBaseRowTotalInclTax($item->getBaseRowTotalInclTax() + $baseTaxBeforeDiscountRounded);
-            }
-        }
-
-        $taxGroups[$rateKey]['totals'][] = max(0, $taxSubtotal);
-        $taxGroups[$rateKey]['base_totals'][] = max(0, $baseTaxSubtotal);
-        $taxGroups[$rateKey]['tax'][] = max(0, $rowTax);
-        $taxGroups[$rateKey]['base_tax'][] = max(0, $baseRowTax);
+    protected function updateShippingTaxInfo(Address $address, $shippingTaxDetails, $baseShippingTaxDetails)
+    {
+        $address->setTotalAmount('shipping', $shippingTaxDetails->getRowTotal());
+        $address->setBaseTotalAmount('shipping', $baseShippingTaxDetails->getRowTotal());
+        $address->setShippingTaxAmount($shippingTaxDetails->getRowTax());
+        $address->setBaseShippingTaxAmount($baseShippingTaxDetails->getRowTax());
+        $address->setTotalAmount('shipping_hidden_tax', $shippingTaxDetails->getDiscountTaxCompensationAmount());
+        $address->setBaseTotalAmount('shipping_hidden_tax', $baseShippingTaxDetails->getDiscountTaxCompensationAmount());
+
+        $address->setShippingInclTax($shippingTaxDetails->getRowTotalInclTax());
+        $address->setBaseShippingInclTax($baseShippingTaxDetails->getRowTotalInclTax());
+
+        if ($this->_config->discountTax($this->_store)) {
+            $address->setShippingAmountForDiscount($shippingTaxDetails->getRowTotalInclTax());
+            $address->setBaseShippingAmountForDiscount($baseShippingTaxDetails->getRowTotalInclTax());
+        }
+
+        //Add taxes applied to shipping to applied taxes
+        $appliedTaxes = $shippingTaxDetails->getAppliedTaxes();
+        $baseAppliedTaxes = $baseShippingTaxDetails->getAppliedTaxes();
+        $appliedTaxesArray = $this->convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes);
+        $this->_saveAppliedTaxes(
+            $address,
+            $appliedTaxesArray,
+            $shippingTaxDetails->getRowTax(),
+            $baseShippingTaxDetails->getRowTax(),
+            $shippingTaxDetails->getTaxPercent()
+        );
 
         return $this;
     }
 
     /**
-     * Round price based on previous rounding operation delta
+     * Convert appliedTax data object from tax calculation service to internal array format
      *
-     * @param float $price
-     * @param string $rate
-     * @param bool $direction price including or excluding tax
-     * @param string $type
-     * @return float
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $baseAppliedTaxes
+     * @return array
      */
-    protected function _deltaRound($price, $rate, $direction, $type = 'regular')
+    protected function convertAppliedTaxes($appliedTaxes, $baseAppliedTaxes)
     {
-        if ($price) {
-            $rate = (string)$rate;
-            $type = $type . $direction;
-            // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
-            $delta = isset($this->_roundingDeltas[$type][$rate]) ? $this->_roundingDeltas[$type][$rate] : 0.000001;
-            $price += $delta;
-            $this->_roundingDeltas[$type][$rate] = $price - $this->_calculator->round($price);
-            $price = $this->_calculator->round($price);
+        $appliedTaxesArray = [];
+
+        if (!$appliedTaxes || !$baseAppliedTaxes) {
+            return $appliedTaxesArray;
         }
-        return $price;
-    }
 
-    /**
-     * Recalculate parent item amounts base on children data
-     *
-     * @param   AbstractItem $item
-     * @return  $this
-     */
-    protected function _recalculateParent(AbstractItem $item)
-    {
-        $rowTaxAmount = 0;
-        $baseRowTaxAmount = 0;
-        foreach ($item->getChildren() as $child) {
-            $rowTaxAmount += $child->getTaxAmount();
-            $baseRowTaxAmount += $child->getBaseTaxAmount();
+        foreach ($appliedTaxes as $taxId => $appliedTax) {
+            $baseAppliedTax = $baseAppliedTaxes[$taxId];
+            $rateDataObjects = $appliedTax->getRates();
+
+            $rates = [];
+            foreach ($rateDataObjects as $rateDataObject) {
+                $rates[] = [
+                    'percent' => $rateDataObject->getPercent(),
+                    'code' => $rateDataObject->getCode(),
+                    'title' => $rateDataObject->getTitle(),
+                ];
+            }
+
+            $appliedTaxesArray[] = [
+                'amount' => $appliedTax->getAmount(),
+                'base_amount' => $baseAppliedTax->getAmount(),
+                'percent' => $appliedTax->getPercent(),
+                'id' => $appliedTax->getTaxRateKey(),
+                'rates' => $rates,
+            ];
         }
-        $item->setTaxAmount($rowTaxAmount);
-        $item->setBaseTaxAmount($baseRowTaxAmount);
-        return $this;
+
+        return $appliedTaxesArray;
     }
 
     /**
@@ -1263,4 +707,24 @@ class Tax extends AbstractTotal
     {
         return __('Tax');
     }
+
+    /**
+     * Determine whether to include shipping in tax calculation
+     *
+     * @return bool
+     */
+    protected function includeShipping()
+    {
+        return true;
+    }
+
+    /**
+     * Return a flag to indicate whether to process extra subtotal field in the quote
+     *
+     * @return bool
+     */
+    protected function processExtraSubtotalAmount()
+    {
+        return true;
+    }
 }
diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
index 821736f4653f3905fdee894325c73f089fa74936..33032cf2252e75010419aaff7241a35697111784 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Customer.php
@@ -21,35 +21,73 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Tax\Model\TaxClass\Source;
 
 use Magento\Tax\Model\Resource\TaxClass\CollectionFactory;
+use Magento\Tax\Service\V1\Data\TaxClass;
 
+/**
+ * Customer tax class source model.
+ */
 class Customer extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
 {
     /**
-     * @var CollectionFactory
+     * @var \Magento\Tax\Service\V1\TaxClassServiceInterface
      */
-    protected $collectionFactory;
+    protected $taxClassService;
 
     /**
-     * @param CollectionFactory $collectionFactory
+     * @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder
      */
-    public function __construct(CollectionFactory $collectionFactory)
-    {
-        $this->collectionFactory = $collectionFactory;
+    protected $searchCriteriaBuilder;
+
+    /**
+     * @var \Magento\Framework\Service\V1\Data\FilterBuilder
+     */
+    protected $filterBuilder;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService
+     * @param \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param \Magento\Framework\Service\V1\Data\FilterBuilder $filterBuilder
+     */
+    public function __construct(
+        \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService,
+        \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteriaBuilder,
+        \Magento\Framework\Service\V1\Data\FilterBuilder $filterBuilder
+    ) {
+        $this->taxClassService = $taxClassService;
+        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+        $this->filterBuilder = $filterBuilder;
     }
 
     /**
+     * Retrieve all customer tax classes as an options array.
+     *
+     * @param bool $withEmpty
      * @return array
      */
-    public function getAllOptions()
+    public function getAllOptions($withEmpty = false)
     {
         if (!$this->_options) {
-            $this->_options = $this->collectionFactory->create()->addFieldToFilter(
-                'class_type',
-                \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER
-            )->load()->toOptionArray();
+            $filter = $this->filterBuilder
+                ->setField(TaxClass::KEY_TYPE)
+                ->setValue(\Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_CUSTOMER)
+                ->create();
+            $searchCriteria = $this->searchCriteriaBuilder->addFilter([$filter])->create();
+            $searchResults = $this->taxClassService->searchTaxClass($searchCriteria);
+            foreach ($searchResults->getItems() as $taxClass) {
+                $this->_options[] = array(
+                    'value' => $taxClass->getClassId(),
+                    'label' => $taxClass->getClassName()
+                );
+            }
+        }
+        if ($withEmpty) {
+            return array_merge(array(array('value' => '0', 'label' => __('None'))), $this->_options);
         }
         return $this->_options;
     }
diff --git a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
index 7b35e3129d91984c8106c00448727cc001561b8c..d4d7c9ff1e871e051587bccd9d607d4a590ae6d3 100644
--- a/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
+++ b/app/code/Magento/Tax/Model/TaxClass/Source/Product.php
@@ -21,10 +21,31 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Tax\Model\TaxClass\Source;
 
+use Magento\Tax\Service\V1\Data\TaxClass;
+
+/**
+ * Product tax class source model.
+ */
 class Product extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
 {
+    /**
+     * @var \Magento\Tax\Service\V1\taxClassServiceInterface
+     */
+    protected $_taxClassService;
+
+    /**
+     * @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder
+     */
+    protected $_searchCriteriaBuilder;
+
+    /**
+     * @var \Magento\Framework\Service\V1\Data\FilterBuilder
+     */
+    protected $_filterBuilder;
+
     /**
      * Core data
      *
@@ -32,51 +53,63 @@ class Product extends \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource
      */
     protected $_coreData;
 
-    /**
-     * @var \Magento\Tax\Model\Resource\TaxClass\CollectionFactory
-     */
-    protected $_classesFactory;
-
     /**
      * @var \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory
      */
     protected $_optionFactory;
 
     /**
+     * Initialize dependencies.
+     *
      * @param \Magento\Core\Helper\Data $coreData
      * @param \Magento\Tax\Model\Resource\TaxClass\CollectionFactory $classesFactory
      * @param \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory $optionFactory
+     * @param \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService
+     * @param \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param \Magento\Framework\Service\V1\Data\FilterBuilder $filterBuilder
      */
     public function __construct(
         \Magento\Core\Helper\Data $coreData,
         \Magento\Tax\Model\Resource\TaxClass\CollectionFactory $classesFactory,
-        \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory $optionFactory
+        \Magento\Eav\Model\Resource\Entity\Attribute\OptionFactory $optionFactory,
+        \Magento\Tax\Service\V1\TaxClassServiceInterface $taxClassService,
+        \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteriaBuilder,
+        \Magento\Framework\Service\V1\Data\FilterBuilder $filterBuilder
     ) {
         $this->_coreData = $coreData;
         $this->_classesFactory = $classesFactory;
         $this->_optionFactory = $optionFactory;
+        $this->_taxClassService = $taxClassService;
+        $this->_filterBuilder = $filterBuilder;
+        $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
     }
 
     /**
-     * Get all options
+     * Retrieve all product tax class options.
      *
+     * @param bool $withEmpty
      * @return array
      */
-    public function getAllOptions()
+    public function getAllOptions($withEmpty = false)
     {
-        if (is_null($this->_options)) {
-            /** @var $classCollection \Magento\Tax\Model\Resource\TaxClass\Collection */
-            $classCollection = $this->_classesFactory->create();
-            $classCollection->addFieldToFilter(
-                'class_type',
-                \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
-            )->load();
-            $this->_options = $classCollection->toOptionArray();
+        if (!$this->_options) {
+            $filter = $this->_filterBuilder
+                ->setField(TaxClass::KEY_TYPE)
+                ->setValue(\Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_PRODUCT)
+                ->create();
+            $searchCriteria = $this->_searchCriteriaBuilder->addFilter([$filter])->create();
+            $searchResults = $this->_taxClassService->searchTaxClass($searchCriteria);
+            foreach ($searchResults->getItems() as $taxClass) {
+                $this->_options[] = array(
+                    'value' => $taxClass->getClassId(),
+                    'label' => $taxClass->getClassName()
+                );
+            }
         }
-
-        $options = $this->_options;
-        array_unshift($options, array('value' => '0', 'label' => __('None')));
-        return $options;
+        if ($withEmpty) {
+            return array_merge(array(array('value' => '0', 'label' => __('None'))), $this->_options);
+        }
+        return $this->_options;
     }
 
     /**
diff --git a/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php b/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php
index 783a479723347ac927e27c956b602b71539d8c43..d5f511d5a4207cec1db555fd88e96ec55b4f7e96 100644
--- a/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php
+++ b/app/code/Magento/Tax/Pricing/Price/Plugin/AttributePrice.php
@@ -65,10 +65,10 @@ class AttributePrice
 
         $productClassId = $product->getTaxClassId();
 
-        $defaultValue = $this->applyRate($productClassId, false, false, false);
+        $defaultValue = $this->applyRate($productClassId, false, false, false, $result['customerId']);
         $result['defaultTax'] = $defaultValue + $result['defaultTax'];
 
-        $currentTax = $this->applyRate($productClassId);
+        $currentTax = $this->applyRate($productClassId, null, null, null, $result['customerId']);
         $result['currentTax'] = $currentTax + $result['currentTax'];
 
         $adjustment = $product->getPriceInfo()->getAdjustment(\Magento\Tax\Pricing\Adjustment::ADJUSTMENT_CODE);
@@ -86,11 +86,23 @@ class AttributePrice
      * @param null $shippingAddress
      * @param null $billingAddress
      * @param null $customerTaxClass
+     * @param int|null $customerId
      * @return float
      */
-    protected function applyRate($classId, $shippingAddress = null, $billingAddress = null, $customerTaxClass = null)
-    {
-        $rateRequest = $this->calculation->getRateRequest($shippingAddress, $billingAddress, $customerTaxClass);
+    protected function applyRate(
+        $classId,
+        $shippingAddress = null,
+        $billingAddress = null,
+        $customerTaxClass = null,
+        $customerId = null
+    ) {
+        $rateRequest = $this->calculation->getRateRequest(
+            $shippingAddress,
+            $billingAddress,
+            $customerTaxClass,
+            null,
+            $customerId
+        );
         $rateRequest->setProductClassId($classId);
         return $this->calculation->getRate($rateRequest);
     }
diff --git a/app/code/Magento/Tax/Service/V1/Collection/TaxRateCollection.php b/app/code/Magento/Tax/Service/V1/Collection/TaxRateCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..51723253e1576fca2c81f3a2686a69de84eca699
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Collection/TaxRateCollection.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Collection;
+
+use Magento\Core\Model\EntityFactory;
+use Magento\Framework\Service\AbstractServiceCollection;
+use Magento\Framework\Service\V1\Data\FilterBuilder;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Tax\Model\Calculation\Rate\Converter;
+use Magento\Tax\Service\V1\TaxRateServiceInterface;
+use Magento\Tax\Service\V1\Data\TaxRate;
+
+/**
+ * Tax rate collection for a grid backed by Services
+ */
+class TaxRateCollection extends AbstractServiceCollection
+{
+    /**
+     * @var TaxRateServiceInterface
+     */
+    protected $rateService;
+
+    /**
+     * @var Converter
+     */
+    protected $rateConverter;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param FilterBuilder $filterBuilder
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param TaxRateServiceInterface $rateService
+     * @param Converter $rateConverter
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        FilterBuilder $filterBuilder,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        TaxRateServiceInterface $rateService,
+        Converter $rateConverter
+    ) {
+        parent::__construct($entityFactory, $filterBuilder, $searchCriteriaBuilder);
+        $this->rateService = $rateService;
+        $this->rateConverter = $rateConverter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadData($printQuery = false, $logQuery = false)
+    {
+        if (!$this->isLoaded()) {
+            $searchCriteria = $this->getSearchCriteria();
+            $searchResults = $this->rateService->searchTaxRates($searchCriteria);
+            $this->_totalRecords = $searchResults->getTotalCount();
+            foreach ($searchResults->getItems() as $taxRate) {
+                $this->_addItem($this->createTaxRateCollectionItem($taxRate));
+            }
+            $this->_setIsLoaded();
+        }
+        return $this;
+    }
+
+    /**
+     * Creates a collection item that represents a tax rate for the tax rates grid.
+     *
+     * @param TaxRate $taxRate Input data for creating the item.
+     * @return \Magento\Framework\Object Collection item that represents a tax rate
+     */
+    protected function createTaxRateCollectionItem(TaxRate $taxRate)
+    {
+        $collectionItem = new \Magento\Framework\Object();
+        $collectionItem->setTaxCalculationRateId($taxRate->getId());
+        $collectionItem->setCode($taxRate->getCode());
+        $collectionItem->setTaxCountryId($taxRate->getCountryId());
+        $collectionItem->setTaxRegionId($taxRate->getRegionId());
+        $collectionItem->setRegionName($taxRate->getRegionName());
+        $collectionItem->setTaxPostcode($taxRate->getPostcode());
+        $collectionItem->setRate($taxRate->getPercentageRate());
+        $collectionItem->setTitles($this->rateConverter->createTitleArrayFromServiceObject($taxRate));
+
+        if ($taxRate->getZipRange() != null) {
+            $zipRange = $taxRate->getZipRange();
+
+            /* must be a "1" for existing code (e.g. JavaScript) to work */
+            $collectionItem->setZipIsRange("1");
+            $collectionItem->setZipFrom($zipRange->getFrom());
+            $collectionItem->setZipTo($zipRange->getTo());
+        } else {
+            $collectionItem->setZipIsRange(null);
+            $collectionItem->setZipFrom(null);
+            $collectionItem->setZipTo(null);
+        }
+
+        return $collectionItem;
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php b/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php
new file mode 100644
index 0000000000000000000000000000000000000000..384b30432f8388bf588bf33877aa0a7e03fe3160
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Collection/TaxRuleCollection.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Collection;
+
+use Magento\Core\Model\EntityFactory;
+use Magento\Framework\Service\AbstractServiceCollection;
+use Magento\Framework\Service\V1\Data\FilterBuilder;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Tax\Model\Calculation\TaxRuleConverter;
+use Magento\Tax\Service\V1\TaxRuleServiceInterface;
+use Magento\Tax\Service\V1\Data\TaxRule;
+
+/**
+ * Tax rule collection for a grid backed by Services
+ */
+class TaxRuleCollection extends AbstractServiceCollection
+{
+    /**
+     * @var TaxRuleServiceInterface
+     */
+    protected $ruleService;
+
+    /**
+     * @var TaxRuleConverter
+     */
+    protected $ruleConverter;
+
+    /**
+     * Initialize dependencies.
+     *
+     * @param EntityFactory $entityFactory
+     * @param FilterBuilder $filterBuilder
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param TaxRuleServiceInterface $ruleService
+     * @param TaxRuleConverter $ruleConverter
+     */
+    public function __construct(
+        EntityFactory $entityFactory,
+        FilterBuilder $filterBuilder,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        TaxRuleServiceInterface $ruleService,
+        TaxRuleConverter $ruleConverter
+    ) {
+        parent::__construct($entityFactory, $filterBuilder, $searchCriteriaBuilder);
+        $this->ruleService = $ruleService;
+        $this->ruleConverter = $ruleConverter;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function loadData($printQuery = false, $logQuery = false)
+    {
+        if (!$this->isLoaded()) {
+            $searchCriteria = $this->getSearchCriteria();
+            $searchResults = $this->ruleService->searchTaxRules($searchCriteria);
+            $this->_totalRecords = $searchResults->getTotalCount();
+            foreach ($searchResults->getItems() as $taxRule) {
+                $this->_addItem($this->createTaxRuleCollectionItem($taxRule));
+            }
+            $this->_setIsLoaded();
+        }
+        return $this;
+    }
+
+    /**
+     * Creates a collection item that represents a tax rule for the tax rules grid.
+     *
+     * @param TaxRule $taxRule Input data for creating the item.
+     * @return \Magento\Framework\Object Collection item that represents a tax rule
+     */
+    protected function createTaxRuleCollectionItem(TaxRule $taxRule)
+    {
+        $collectionItem = new \Magento\Framework\Object();
+        $collectionItem->setTaxCalculationRuleId($taxRule->getId());
+        $collectionItem->setCode($taxRule->getCode());
+        /* should cast to string so that some optional fields won't be null on the collection grid pages */
+        $collectionItem->setPriority((string)$taxRule->getPriority());
+        $collectionItem->setPosition((string)$taxRule->getSortOrder());
+        $collectionItem->setCalculateSubtotal((string)$taxRule->getCalculateSubtotal());
+        $collectionItem->setCustomerTaxClasses($taxRule->getCustomerTaxClassIds());
+        $collectionItem->setProductTaxClasses($taxRule->getProductTaxClassIds());
+        $collectionItem->setTaxRates($taxRule->getTaxRateIds());
+        return $collectionItem;
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php
index 5d1d4fd7a24a4091ed604a80c2dffad1316e4977..1411a71a06cd09626ae800b434e680741a849aea 100644
--- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php
+++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetails.php
@@ -36,6 +36,8 @@ class QuoteDetails extends \Magento\Framework\Service\Data\AbstractObject
     const KEY_CUSTOMER_TAX_CLASS_ID = 'customer_tax_class_id';
 
     const KEY_ITEMS = 'items';
+
+    const KEY_CUSTOMER_ID = 'customer_id';
     /**#@-*/
 
     /**
@@ -69,7 +71,17 @@ class QuoteDetails extends \Magento\Framework\Service\Data\AbstractObject
     }
 
     /**
-     * Get quote items
+     * Get customer id
+     *
+     * @return id|null
+     */
+    public function getCustomerId()
+    {
+        return $this->_get(self::KEY_CUSTOMER_ID);
+    }
+
+    /**
+     * Get customer data
      *
      * @return \Magento\Tax\Service\V1\Data\QuoteDetails\Item[]|null
      */
diff --git a/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php
index 1b38c8bc78abe38f4ceccb8d7fa1e61bf95e621d..08382bba602c029f2951abf5176f99d808f4d730 100644
--- a/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/QuoteDetailsBuilder.php
@@ -54,6 +54,26 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject
         $this->addressBuilder = $addressBuilder;
     }
 
+    /**
+     * Convenience method to return item builder
+     *
+     * @return QuoteDetails\ItemBuilder
+     */
+    public function getItemBuilder()
+    {
+        return $this->itemBuilder;
+    }
+
+    /**
+     * Convenience method to return address builder
+     *
+     * @return \Magento\Customer\Service\V1\Data\AddressBuilder
+     */
+    public function getAddressBuilder()
+    {
+        return $this->addressBuilder;
+    }
+
     /**
      * Set customer billing address
      *
@@ -87,6 +107,17 @@ class QuoteDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObject
         return $this->_set(QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID, $taxClassId);
     }
 
+    /**
+     * Set customer id
+     *
+     * @param int $customerId
+     * @return $this
+     */
+    public function setCustomerId($customerId)
+    {
+        return $this->_set(QuoteDetails::KEY_CUSTOMER_ID, $customerId);
+    }
+
     /**
      * Set quote items
      *
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxClass.php b/app/code/Magento/Tax/Service/V1/Data/TaxClass.php
index f39d25bfeb19f80ae2b5fff3ac85ac634450dc81..228dfbc9195bf883b0887a657a87d6529feae2f0 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxClass.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxClass.php
@@ -30,13 +30,7 @@ namespace Magento\Tax\Service\V1\Data;
 class TaxClass extends \Magento\Framework\Service\Data\AbstractObject
 {
     /**#@+
-     * Tax class type.
-     */
-    const TYPE_CUSTOMER = 'CUSTOMER';
-    const TYPE_PRODUCT = 'PRODUCT';
-    /**#@-*/
-
-    /**#@+
+     *
      * Tax class field key.
      */
     const KEY_ID = 'class_id';
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResults.php b/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResults.php
new file mode 100644
index 0000000000000000000000000000000000000000..b06d170acab0452803245c202a004adcb3619dea
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResults.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+use Magento\Framework\Service\V1\Data\SearchResults;
+
+/**
+ * Data object for Tax class search results.
+ */
+class TaxClassSearchResults extends SearchResults
+{
+    /**
+     * Get items
+     *
+     * @return \Magento\Tax\Service\V1\Data\TaxClass[]
+     */
+    public function getItems()
+    {
+        return parent::getItems();
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResultsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResultsBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf268bc0cb98b4004c5dc414ee5c685ecffe2d83
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxClassSearchResultsBuilder.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+use Magento\Framework\Service\Data\ObjectFactory;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Framework\Service\V1\Data\AbstractSearchResultsBuilder;
+
+/**
+ * Builder for the TaxClassSearchResults Service Data Object
+ *
+ * @method TaxClassSearchResults create()
+ */
+class TaxClassSearchResultsBuilder extends AbstractSearchResultsBuilder
+{
+    /**
+     * Constructor
+     *
+     * @param ObjectFactory $objectFactory
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param TaxClassBuilder $taxClassObjectBuilder
+     */
+    public function __construct(
+        ObjectFactory $objectFactory,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        TaxClassBuilder $taxClassObjectBuilder
+    ) {
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $taxClassObjectBuilder);
+    }
+
+    /**
+     * Set tax class items
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxClass[] $taxClassItems
+     * @return $this
+     */
+    public function setItems($taxClassItems)
+    {
+        return parent::setItems($taxClassItems);
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails.php
index 5f7423b39914f9769f640845e76e9adcf94e4e57..eb8463ef396cb892b64447bfdefbcdc607eaeb8a 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails.php
@@ -33,7 +33,7 @@ class TaxDetails extends \Magento\Framework\Service\Data\AbstractObject
 
     const KEY_TAX_AMOUNT = 'tax_amount';
 
-    const KEY_DISCOUNT_AMOUNT = 'discount_amount';
+    const KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT = 'discount_tax_compensation_amount';
 
     const KEY_APPLIED_TAXES = 'applied_taxes';
 
@@ -66,9 +66,9 @@ class TaxDetails extends \Magento\Framework\Service\Data\AbstractObject
      *
      * @return float
      */
-    public function getDiscountAmount()
+    public function getDiscountTaxCompensationAmount()
     {
-        return $this->_get(self::KEY_DISCOUNT_AMOUNT);
+        return $this->_get(self::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/AppliedTaxBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/AppliedTaxBuilder.php
index 7298e045b640972ce6809fb0c14d43dbbcd093d1..58186bc3aef8e01610b1d96a46a8a86b0af8ec05 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/AppliedTaxBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/AppliedTaxBuilder.php
@@ -51,6 +51,16 @@ class AppliedTaxBuilder extends \Magento\Framework\Service\Data\AbstractObjectBu
         $this->appliedTaxRateBuilder = $appliedTaxRateBuilder;
     }
 
+    /**
+     * Convenience method that returns AppliedTaxRateBuilder
+     *
+     * @return AppliedTaxRateBuilder
+     */
+    public function getAppliedTaxRateBuilder()
+    {
+        return $this->appliedTaxRateBuilder;
+    }
+
     /**
      * Set tax rate key
      *
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php
index 01fe828d14fa3e38145311d3a7ba3ddf123ee137..8146c35a02858ffdad5f56fb181425d2bc4fcdc7 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/Item.php
@@ -41,6 +41,8 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject
 
     const KEY_ROW_TOTAL = 'row_total';
 
+    const KEY_ROW_TOTAL_INCL_TAX = 'row_total_incl_tax';
+
     const KEY_ROW_TAX = 'row_tax';
 
     const KEY_TAXABLE_AMOUNT = 'taxable_amount';
@@ -112,6 +114,16 @@ class Item extends \Magento\Framework\Service\Data\AbstractObject
         return $this->_get(self::KEY_ROW_TOTAL);
     }
 
+    /**
+     * Get row total including tax
+     *
+     * @return float
+     */
+    public function getRowTotalInclTax()
+    {
+        return $this->_get(self::KEY_ROW_TOTAL_INCL_TAX);
+    }
+
     /**
      * Get row tax amount
      *
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php
index 0f03673862939048d26811dc90380cf1375fada3..f10479c1fc686b8fade45467273e8d60eb8c4500 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetails/ItemBuilder.php
@@ -54,6 +54,16 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
         $this->appliedTaxBuilder = $appliedTaxBuilder;
     }
 
+    /**
+     * Convenience getter method for AppliedTaxBuilder
+     *
+     * @return AppliedTaxBuilder
+     */
+    public function getAppliedTaxBuilder()
+    {
+        return $this->appliedTaxBuilder;
+    }
+
     /**
      * Set code (sku or shipping code)
      *
@@ -126,6 +136,18 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
         return $this;
     }
 
+    /**
+     * Set row total including tax
+     *
+     * @param float $rowTotalInclTax
+     * @return $this
+     */
+    public function setRowTotalInclTax($rowTotalInclTax)
+    {
+        $this->_set(Item::KEY_ROW_TOTAL_INCL_TAX, $rowTotalInclTax);
+        return $this;
+    }
+
     /**
      * Set tax amount
      *
@@ -174,6 +196,18 @@ class ItemBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
         return $this;
     }
 
+    /**
+     * Set applied taxes for the item
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes
+     * @return $this
+     */
+    public function setAppliedTaxes($appliedTaxes)
+    {
+        $this->_set(Item::KEY_APPLIED_TAXES, $appliedTaxes);
+        return $this;
+    }
+
     /**
      * {@inheritdoc}
      */
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxDetailsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxDetailsBuilder.php
index 64f0af238f91e881aca95d15fae60fdb4f62f31c..310b5578b015a499eaac0d938e9013a80d6c184b 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxDetailsBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxDetailsBuilder.php
@@ -62,6 +62,16 @@ class TaxDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObjectBu
         $this->taxDetailsItemBuilder = $taxDetailsItemBuilder;
     }
 
+    /**
+     * Convenience method that returns AppliedTaxBuilder
+     *
+     * @return TaxDetails\AppliedTaxBuilder
+     */
+    public function getAppliedTaxBuilder()
+    {
+        return $this->appliedTaxBuilder;
+    }
+
     /**
      * Set subtotal
      *
@@ -92,9 +102,9 @@ class TaxDetailsBuilder extends \Magento\Framework\Service\Data\AbstractObjectBu
      * @param float $discountAmount
      * @return $this
      */
-    public function setDiscountAmount($discountAmount)
+    public function setDiscountCompensationAmount($discountAmount)
     {
-        $this->_set(TaxDetails::KEY_DISCOUNT_AMOUNT, $discountAmount);
+        $this->_set(TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT, $discountAmount);
         return $this;
     }
 
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRate.php b/app/code/Magento/Tax/Service/V1/Data/TaxRate.php
index f7ce7073ffbf09c5beb3ef09b281f34cdfdc29ff..7f16788a0e9ecece10d787da1c9a2a3d6ebe81d4 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRate.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRate.php
@@ -21,26 +21,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Tax\Service\V1\Data;
 
+/**
+ * Service data object for a tax percentage rate associated with a location.
+ */
 class TaxRate extends \Magento\Framework\Service\Data\AbstractObject
 {
     /**#@+
      * Constants defined for keys of array, makes typos less likely
      */
     const KEY_ID = 'id';
-
     const KEY_COUNTRY_ID = 'country_id';
-
     const KEY_REGION_ID = 'region_id';
-
+    const KEY_REGION_NAME = 'region_name';
     const KEY_POSTCODE = 'postcode';
-
     const KEY_ZIP_RANGE = 'zip_range';
-
     const KEY_PERCENTAGE_RATE = 'percentage_rate';
-
     const KEY_CODE = 'code';
+    const KEY_TITLES = 'titles';
     /**#@-*/
 
     /**
@@ -73,6 +73,16 @@ class TaxRate extends \Magento\Framework\Service\Data\AbstractObject
         return $this->_get(self::KEY_REGION_ID);
     }
 
+    /**
+     * Get region name
+     *
+     * @return string|null
+     */
+    public function getRegionName()
+    {
+        return $this->_get(self::KEY_REGION_NAME);
+    }
+
     /**
      * Get postcode
      *
@@ -112,4 +122,14 @@ class TaxRate extends \Magento\Framework\Service\Data\AbstractObject
     {
         return $this->_get(self::KEY_CODE);
     }
+
+    /**
+     * Get tax rate titles
+     *
+     * @return \Magento\Tax\Service\V1\Data\TaxRateTitle[]|null
+     */
+    public function getTitles()
+    {
+        return $this->_get(self::KEY_TITLES);
+    }
 }
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRateBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRateBuilder.php
index 25e6e67aa5286943ccf7978fd3be94c59b53a8cc..5f72c9bd8c1c270b025ab7fae8650fcf2a45cf70 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRateBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRateBuilder.php
@@ -39,18 +39,28 @@ class TaxRateBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuild
      */
     protected $zipRangeBuilder;
 
+    /**
+     * ZipRange builder
+     *
+     * @var TaxRateTitleBuilder
+     */
+    protected $taxRateTitleBuilder;
+
     /**
      * Initialize dependencies.
      *
      * @param ObjectFactory $objectFactory
      * @param ZipRangeBuilder $zipRangeBuilder
+     * @param TaxRateTitleBuilder $taxRateTitleBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
-        ZipRangeBuilder $zipRangeBuilder
+        ZipRangeBuilder $zipRangeBuilder,
+        TaxRateTitleBuilder $taxRateTitleBuilder
     ) {
         parent::__construct($objectFactory);
         $this->zipRangeBuilder = $zipRangeBuilder;
+        $this->taxRateTitleBuilder = $taxRateTitleBuilder;
     }
 
     /**
@@ -89,6 +99,18 @@ class TaxRateBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuild
         return $this;
     }
 
+    /**
+     * Set region name
+     *
+     * @param string $regionName
+     * @return $this
+     */
+    public function setRegionName($regionName)
+    {
+        $this->_set(TaxRate::KEY_REGION_NAME, $regionName);
+        return $this;
+    }
+
     /**
      * Set postcode
      *
@@ -137,6 +159,18 @@ class TaxRateBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuild
         return $this;
     }
 
+    /**
+     * Set tax rate titles
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxRateTitle[] $titles
+     * @return $this
+     */
+    public function setTitles($titles)
+    {
+        $this->_set(TaxRate::KEY_TITLES, $titles);
+        return $this;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -146,6 +180,13 @@ class TaxRateBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuild
             $data[TaxRate::KEY_ZIP_RANGE] =
                 $this->zipRangeBuilder->populateWithArray($data[TaxRate::KEY_ZIP_RANGE])->create();
         }
+        if (array_key_exists(TaxRate::KEY_TITLES, $data)) {
+            $titles = array();
+            foreach ($data[TaxRate::KEY_TITLES] as $titleData) {
+                $titles[] = $this->taxRateTitleBuilder->populateWithArray($titleData)->create();
+            }
+            $data[TaxRate::KEY_TITLES] = $titles;
+        }
         return parent::_setDataValues($data);
     }
 }
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResults.php b/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResults.php
new file mode 100644
index 0000000000000000000000000000000000000000..f753577e6c1eec7132c5144f91cdc31ac61d9506
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResults.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+use Magento\Framework\Service\V1\Data\SearchResults;
+
+/**
+ * TaxRateSearchResults Service Data Object used for the search service requests
+ */
+class TaxRateSearchResults extends SearchResults
+{
+    /**
+     * Get items
+     *
+     * @return \Magento\Tax\Service\V1\Data\TaxRate[]
+     */
+    public function getItems()
+    {
+        return parent::getItems();
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..4314ccbcef0f529dc548249fa31f6df5acaa15a6
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilder.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+use Magento\Framework\Service\Data\ObjectFactory;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Framework\Service\V1\Data\AbstractSearchResultsBuilder;
+
+/**
+ * Builder for the TaxRateSearchResults Service Data Object
+ *
+ * @method TaxRateSearchResults create()
+ */
+class TaxRateSearchResultsBuilder extends AbstractSearchResultsBuilder
+{
+    /**
+     * Constructor
+     *
+     * @param ObjectFactory $objectFactory
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param TaxRateBuilder $taxRateObjectBuilder
+     */
+    public function __construct(
+        ObjectFactory $objectFactory,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        TaxRateBuilder $taxRateObjectBuilder
+    ) {
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $taxRateObjectBuilder);
+    }
+
+    /**
+     * Set tax rate items
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxRate[] $taxRateItems
+     * @return $this
+     */
+    public function setItems($taxRateItems)
+    {
+        return parent::setItems($taxRateItems);
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRateTitle.php b/app/code/Magento/Tax/Service/V1/Data/TaxRateTitle.php
new file mode 100644
index 0000000000000000000000000000000000000000..f862c60409cbda7b5462972d4bbd88c5ac200142
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRateTitle.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+/**
+ * A localized tax rate title associated with a store view.
+ */
+class TaxRateTitle extends \Magento\Framework\Service\Data\AbstractObject
+{
+    /**#@+
+     *
+     * Tax rate field key.
+     */
+    const KEY_STORE_ID = 'store_id';
+
+    const KEY_VALUE_ID = 'value';
+    /**#@-*/
+
+    /**
+     * Get store id
+     *
+     * @return string
+     */
+    public function getStoreId()
+    {
+        return $this->_get(self::KEY_STORE_ID);
+    }
+
+    /**
+     * Get title value
+     *
+     * @return string
+     */
+    public function getValue()
+    {
+        return $this->_get(self::KEY_VALUE_ID);
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRateTitleBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRateTitleBuilder.php
new file mode 100644
index 0000000000000000000000000000000000000000..f762c09fcf16a428a4896ac4f31e68c96300f410
--- /dev/null
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRateTitleBuilder.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Data;
+
+/**
+ * TaxRateTitle data builder
+ *
+ * @method TaxRateTitle create()
+ */
+class TaxRateTitleBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
+{
+    /**
+     * Set store id
+     *
+     * @param int $storeId
+     * @return $this
+     */
+    public function setStoreId($storeId)
+    {
+        $this->_set(TaxRateTitle::KEY_STORE_ID, $storeId);
+        return $this;
+    }
+
+    /**
+     * Set title value
+     *
+     * @param string $value
+     * @return $this
+     */
+    public function setValue($value)
+    {
+        $this->_set(TaxRateTitle::KEY_VALUE_ID, $value);
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRule.php b/app/code/Magento/Tax/Service/V1/Data/TaxRule.php
index 0a977d023a9868b2bf6bb4ed6e67b4c76d1405e1..60a9897a05bc777d10475510bbbae4bc8492a874 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRule.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRule.php
@@ -47,6 +47,8 @@ class TaxRule extends AbstractObject
     const PRIORITY = 'priority';
 
     const SORT_ORDER = 'sort_order';
+
+    const CALCULATE_SUBTOTAL = 'calculate_subtotal';
     /**#@-*/
 
     /**
@@ -118,4 +120,14 @@ class TaxRule extends AbstractObject
     {
         return $this->_get(self::SORT_ORDER);
     }
+
+    /**
+     * Get calculate subtotal.
+     *
+     * @return int|null
+     */
+    public function getCalculateSubtotal()
+    {
+        return $this->_get(self::CALCULATE_SUBTOTAL);
+    }
 }
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php
index 5893130941fb6c0c7b9e2ec1795cf8a85b4b9454..82bbb0d517a557495fc9e982345ca1f304f2660e 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRuleBuilder.php
@@ -29,7 +29,7 @@ use Magento\Framework\Service\Data\ObjectFactory;
 /**
  * Builder for the TaxRule Service Data Object
  *
- * @method TaxRule create()
+ * @method \Magento\Tax\Service\V1\Data\TaxRule create()
  */
 class TaxRuleBuilder extends AbstractObjectBuilder
 {
@@ -116,7 +116,7 @@ class TaxRuleBuilder extends AbstractObjectBuilder
      */
     public function setPriority($priority)
     {
-        return $this->_set(TaxRule::PRIORITY, $priority);
+        return $this->_set(TaxRule::PRIORITY, (int)$priority);
     }
 
     /**
@@ -127,6 +127,17 @@ class TaxRuleBuilder extends AbstractObjectBuilder
      */
     public function setSortOrder($sortOrder)
     {
-        return $this->_set(TaxRule::SORT_ORDER, $sortOrder);
+        return $this->_set(TaxRule::SORT_ORDER, (int)$sortOrder);
+    }
+
+    /**
+     * Set calculate subtotal.
+     *
+     * @param int $calculateSubtotal
+     * @return $this
+     */
+    public function setCalculateSubtotal($calculateSubtotal)
+    {
+        return $this->_set(TaxRule::CALCULATE_SUBTOTAL, (int)$calculateSubtotal);
     }
 }
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResults.php b/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResults.php
index 23ffa398558bd92d99952be275b53a1228243658..e67aef7bf7da0499743caa73f91fd27770c571ef 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResults.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResults.php
@@ -24,12 +24,12 @@
 
 namespace Magento\Tax\Service\V1\Data;
 
-use Magento\Customer\Service\V1\Data\SearchResults as CustomerServiceDataSearchResults;
+use Magento\Framework\Service\V1\Data\SearchResults;
 
 /**
  * TaxRuleSearchResults Service Data Object used for the search service requests
  */
-class TaxRuleSearchResults extends CustomerServiceDataSearchResults
+class TaxRuleSearchResults extends SearchResults
 {
     /**
      * Get items
diff --git a/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResultsBuilder.php b/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResultsBuilder.php
index 2e4571ea420979098c89a522576be426445ee8b6..6ba574c682a7cbc8296030ba0fd0db46c6bfb1b4 100644
--- a/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResultsBuilder.php
+++ b/app/code/Magento/Tax/Service/V1/Data/TaxRuleSearchResultsBuilder.php
@@ -40,14 +40,14 @@ class TaxRuleSearchResultsBuilder extends AbstractSearchResultsBuilder
      *
      * @param ObjectFactory $objectFactory
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
-     * @param TaxRuleBuilder $taxRuleObjectBuilder
+     * @param TaxRuleBuilder $itemObjectBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
         SearchCriteriaBuilder $searchCriteriaBuilder,
-        TaxRuleBuilder $taxRuleObjectBuilder
+        TaxRuleBuilder $itemObjectBuilder
     ) {
-        parent::__construct($objectFactory, $searchCriteriaBuilder, $taxRuleObjectBuilder);
+        parent::__construct($objectFactory, $searchCriteriaBuilder, $itemObjectBuilder);
     }
 
     /**
diff --git a/app/code/Magento/Tax/Service/V1/TaxCalculationService.php b/app/code/Magento/Tax/Service/V1/TaxCalculationService.php
index 564d817e075111c75b0b2b90453ee8a56acd8dfa..928779b7911480aa82f37e67609a1cfac6c41365 100644
--- a/app/code/Magento/Tax/Service/V1/TaxCalculationService.php
+++ b/app/code/Magento/Tax/Service/V1/TaxCalculationService.php
@@ -24,15 +24,18 @@
 
 namespace Magento\Tax\Service\V1;
 
+use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
+use Magento\Store\Model\StoreManagerInterface;
 use Magento\Tax\Model\Calculation;
 use Magento\Tax\Model\Resource\Sales\Order\Tax;
 use Magento\Tax\Service\V1\Data\QuoteDetails;
 use Magento\Tax\Service\V1\Data\QuoteDetails\Item as QuoteDetailsItem;
 use Magento\Tax\Service\V1\Data\TaxDetails;
+use Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax;
+use Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxRate;
 use Magento\Tax\Service\V1\Data\TaxDetails\Item as TaxDetailsItem;
 use Magento\Tax\Service\V1\Data\TaxDetails\ItemBuilder as TaxDetailsItemBuilder;
 use Magento\Tax\Service\V1\Data\TaxDetailsBuilder;
-use Magento\Store\Model\StoreManagerInterface;
 
 /**
  * Tax Calculation Service
@@ -40,6 +43,16 @@ use Magento\Store\Model\StoreManagerInterface;
  */
 class TaxCalculationService implements TaxCalculationServiceInterface
 {
+    /**#@+
+     * Constants for delta rounding key
+     */
+    const KEY_REGULAR_DELTA_ROUNDING = 'regular';
+
+    const KEY_APPLIED_TAX_DELTA_ROUNDING = 'applied_tax_amount';
+
+    const KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING = 'tax_after_discount';
+    /**#@-*/
+
     /**
      * Tax calculation model
      *
@@ -74,6 +87,13 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      */
     protected $roundingDeltas;
 
+    /**
+     * Array to hold discount compensations for items
+     *
+     * @var array
+     */
+    protected $discountTaxCompensations;
+
     /**
      * Tax details item builder
      *
@@ -100,6 +120,11 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      */
     private $parentToChildren;
 
+    /**
+     * @var CustomerAccountServiceInterface
+     */
+    protected $customerAccountService;
+
     /**
      * Constructor
      *
@@ -108,19 +133,22 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      * @param TaxDetailsBuilder $taxDetailsBuilder
      * @param TaxDetailsItemBuilder $taxDetailsItemBuilder
      * @param StoreManagerInterface $storeManager
+     * @param CustomerAccountServiceInterface $customerAccountService
      */
     public function __construct(
         Calculation $calculation,
         \Magento\Tax\Model\Config $config,
         TaxDetailsBuilder $taxDetailsBuilder,
         TaxDetailsItemBuilder $taxDetailsItemBuilder,
-        StoreManagerInterface $storeManager
+        StoreManagerInterface $storeManager,
+        CustomerAccountServiceInterface $customerAccountService
     ) {
         $this->calculator = $calculation;
         $this->config = $config;
         $this->taxDetailsBuilder = $taxDetailsBuilder;
         $this->taxDetailsItemBuilder = $taxDetailsItemBuilder;
         $this->storeManager = $storeManager;
+        $this->customerAccountService = $customerAccountService;
     }
 
     /**
@@ -136,7 +164,9 @@ class TaxCalculationService implements TaxCalculationServiceInterface
         $taxDetailsData = [
             TaxDetails::KEY_SUBTOTAL => 0.0,
             TaxDetails::KEY_TAX_AMOUNT => 0.0,
-            TaxDetails::KEY_DISCOUNT_AMOUNT => 0.0
+            TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT => 0.0,
+            TaxDetails::KEY_APPLIED_TAXES => [],
+            TaxDetails::KEY_ITEMS => [],
         ];
 
         $items = $quoteDetails->getItems();
@@ -145,7 +175,7 @@ class TaxCalculationService implements TaxCalculationServiceInterface
         }
         $this->computeRelationships($items);
 
-        $addressRequest = $this->getAddressTaxRequest($quoteDetails, $storeId);
+        $addressRequest = $this->getAddressTaxRequest($quoteDetails, $storeId, $quoteDetails->getCustomerId());
         if ($this->config->priceIncludesTax($storeId)) {
             $storeRequest = $this->getStoreTaxRequest($storeId);
             $classIds = [];
@@ -168,13 +198,18 @@ class TaxCalculationService implements TaxCalculationServiceInterface
 
         // init rounding deltas for this quote
         $this->roundingDeltas = [];
+        // init discount tax compensations array
+        $this->discountTaxCompensations = [];
         $processedItems = [];
         /** @var QuoteDetailsItem $item */
         foreach ($this->keyedItems as $item) {
             if (isset($this->parentToChildren[$item->getCode()])) {
                 $processedChildren = [];
                 foreach ($this->parentToChildren[$item->getCode()] as $child) {
-                    $processedChildren[] = $this->processItem($child, $addressRequest, $storeId);
+                    $processedItem = $this->processItem($child, $addressRequest, $storeId);
+                    $taxDetailsData = $this->aggregateItemData($taxDetailsData, $processedItem);
+                    $processedItems[$processedItem->getCode()] = $processedItem;
+                    $processedChildren[] = $processedItem;
                 }
                 $processedItemBuilder = $this->calculateParent($processedChildren, $item->getQuantity());
                 $processedItemBuilder->setCode($item->getCode());
@@ -182,14 +217,63 @@ class TaxCalculationService implements TaxCalculationServiceInterface
                 $processedItem = $processedItemBuilder->create();
             } else {
                 $processedItem = $this->processItem($item, $addressRequest, $storeId);
+                $taxDetailsData = $this->aggregateItemData($taxDetailsData, $processedItem);
             }
-            $processedItems[] = $processedItem;
-            $taxDetailsData = $this->addSubtotalAmount($taxDetailsData, $processedItem);
+            $processedItems[$processedItem->getCode()] = $processedItem;
         }
 
         return $this->taxDetailsBuilder->populateWithArray($taxDetailsData)->setItems($processedItems)->create();
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function getDefaultCalculatedRate(
+        $productTaxClassID,
+        $customerId = null,
+        $storeId = null
+    ) {
+        return $this->getRate($productTaxClassID, $customerId, $storeId, true);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getCalculatedRate(
+        $productTaxClassID,
+        $customerId = null,
+        $storeId = null
+    ) {
+        return $this->getRate($productTaxClassID, $customerId, $storeId);
+    }
+
+    /**
+     * Calculate rate based on default parameter
+     *
+     * @param int $productTaxClassID
+     * @param int|null $customerId
+     * @param string|null $storeId
+     * @param bool $isDefault
+     * @return float
+     */
+    protected function getRate(
+        $productTaxClassID,
+        $customerId = null,
+        $storeId = null,
+        $isDefault = false
+    ) {
+        if (is_null($storeId)) {
+            $storeId = $this->storeManager->getStore()->getStoreId();
+        }
+        if (!$isDefault) {
+            $addressRequestObject = $this->calculator->getRateRequest(null, null, null, $storeId, $customerId);
+        } else {
+            $addressRequestObject = $this->calculator->getDefaultRateRequest($storeId, $customerId);
+        }
+        $addressRequestObject->setProductClassId($productTaxClassID);
+        return $this->calculator->getRate($addressRequestObject);
+    }
+
     /**
      * Computes relationships between items, primarily the child to parent relationship.
      *
@@ -214,15 +298,17 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      *
      * @param QuoteDetails $quoteDetails
      * @param int $storeId
+     * @param int $customerId
      * @return \Magento\Framework\Object
      */
-    protected function getAddressTaxRequest(QuoteDetails $quoteDetails, $storeId)
+    protected function getAddressTaxRequest(QuoteDetails $quoteDetails, $storeId, $customerId)
     {
         return $this->calculator->getRateRequest(
             $quoteDetails->getShippingAddress(),
             $quoteDetails->getBillingAddress(),
             $quoteDetails->getCustomerTaxClassId(),
-            $storeId
+            $storeId,
+            $customerId
         );
     }
 
@@ -238,7 +324,7 @@ class TaxCalculationService implements TaxCalculationServiceInterface
     }
 
     /**
-     * Calculate item price and row total with customized rounding level
+     * Calculate item tax with customized rounding level
      *
      * @param QuoteDetailsItem $item
      * @param \Magento\Framework\Object $taxRequest
@@ -254,7 +340,6 @@ class TaxCalculationService implements TaxCalculationServiceInterface
             case Calculation::CALC_UNIT_BASE:
                 return $this->unitBaseCalculation($item, $taxRequest, $storeId);
             case Calculation::CALC_ROW_BASE:
-                return $this->rowBaseCalculation($item, $taxRequest, $storeId);
             case Calculation::CALC_TOTAL_BASE:
                 return $this->totalBaseCalculation($item, $taxRequest, $storeId);
             default:
@@ -264,189 +349,370 @@ class TaxCalculationService implements TaxCalculationServiceInterface
 
     /**
      * Calculate item price and row total including/excluding tax based on unit price rounding level
+     * This function also saves applied tax per tax rate for the item
      *
      * @param QuoteDetailsItem $item
-     * @param \Magento\Framework\Object $taxRequest
+     * @param \Magento\Framework\Object $taxRateRequest
      * @param int $storeId
      * @return TaxDetailsItem
      */
     protected function unitBaseCalculation(
         QuoteDetailsItem $item,
-        \Magento\Framework\Object $taxRequest,
+        \Magento\Framework\Object $taxRateRequest,
         $storeId
     ) {
-        $taxRequest->setProductClassId($item->getTaxClassId());
-        $storeRate = $this->calculator->getStoreRate($taxRequest, $storeId);
-        $rate = $this->calculator->getRate($taxRequest);
+        /** @var  \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */
+        $appliedTaxes = [];
+        $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder();
+        $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder();
+
+        $taxRateRequest->setProductClassId($item->getTaxClassId());
+        $appliedRates = $this->calculator->getAppliedRates($taxRateRequest);
+        $rate = $this->calculator->getRate($taxRateRequest);
+
         $quantity = $this->getTotalQuantity($item);
-        $price = $taxPrice = $this->calculator->round($item->getUnitPrice());
-        $subtotal = $taxSubtotal = $this->calcRowTotal($item);
+        $price = $priceInclTax = $this->calculator->round($item->getUnitPrice());
+        $rowTotal = $rowTotalInclTax = $this->calcRowTotal($item);
+
+        $discountAmount = $item->getDiscountAmount();
+        $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($storeId);
+
+        $discountTaxCompensationAmount = 0;
+
         if ($item->getTaxIncluded()) {
-            if ($taxRequest->getSameRateAsStore() || ($rate == $storeRate)) {
-                $taxable = $price;
-                $tax = $this->calculator->calcTaxAmount($taxable, $rate, true);
-                $price = $price - $tax;
-                $subtotal = $price * $quantity;
+            if ($taxRateRequest->getSameRateAsStore()) {
+                $uniTax = $this->calculator->calcTaxAmount($priceInclTax, $rate, true);
+                $price = $priceInclTax - $uniTax;
+                $rowTax = $uniTax * $quantity;
+                $rowTotal = $price * $quantity;
             } else {
-                $taxPrice = $this->calculatePriceInclTax($price, $storeRate, $rate);
-                $taxable = $taxPrice;
-                $tax = $this->calculator->calcTaxAmount($taxable, $rate, true, true);
-                $price = $taxPrice - $tax;
-                $taxSubtotal = $taxPrice * $quantity;
-                $subtotal = $price * $quantity;
+                $storeRate = $this->calculator->getStoreRate($taxRateRequest, $storeId);
+                $priceInclTax = $this->calculatePriceInclTax($price, $storeRate, $rate);
+                $uniTax = $this->calculator->calcTaxAmount($priceInclTax, $rate, true, true);
+                $rowTax = $uniTax * $quantity;
+                $price = $priceInclTax - $uniTax;
+                $rowTotalInclTax = $priceInclTax * $quantity;
+                $rowTotal = $price * $quantity;
             }
-        } else {
+
+            //Handle discount
+            if ($discountAmount && $applyTaxAfterDiscount) {
+                //TODO: handle originalDiscountAmount
+                $unitDiscountAmount = $discountAmount / $quantity;
+                $taxableAmount = max($priceInclTax - $unitDiscountAmount, 0);
+                $unitTaxAfterDiscount = $this->calculator->calcTaxAmount(
+                    $taxableAmount,
+                    $rate,
+                    true,
+                    true
+                );
+
+                // Set discount tax compensation
+                $unitDiscountTaxCompensationAmount = $uniTax - $unitTaxAfterDiscount;
+                $discountTaxCompensationAmount = $unitDiscountTaxCompensationAmount * $quantity;
+                $rowTax = $unitTaxAfterDiscount * $quantity;
+            }
+
+            //save applied taxes
+            $appliedTaxes = $this->getAppliedTaxes($appliedTaxBuilder, $rowTax, $rate, $appliedRates);
+        } else { //catalog price does not include tax
             $taxable = $price;
-            $appliedRates = $this->calculator->getAppliedRates($taxRequest);
-            $taxes = [];
+            $appliedRates = $this->calculator->getAppliedRates($taxRateRequest);
+            $unitTaxes = [];
+            $unitTaxesBeforeDiscount = [];
+            //Apply each tax rate separately
             foreach ($appliedRates as $appliedRate) {
+                $taxId = $appliedRate['id'];
                 $taxRate = $appliedRate['percent'];
-                $taxes[] = $this->calculator->calcTaxAmount($taxable, $taxRate, false);
+                $unitTaxPerRate = $this->calculator->calcTaxAmount($taxable, $taxRate, false);
+                $unitTaxAfterDiscount = $unitTaxPerRate;
+
+                //Handle discount
+                if ($discountAmount && $applyTaxAfterDiscount) {
+                    //TODO: handle originalDiscountAmount
+                    $unitDiscountAmount = $discountAmount / $quantity;
+                    $taxableAmount = max($priceInclTax - $unitDiscountAmount, 0);
+                    $unitTaxAfterDiscount = $this->calculator->calcTaxAmount(
+                        $taxableAmount,
+                        $taxRate,
+                        false,
+                        true
+                    );
+                }
+                $appliedTaxes[$taxId] = $this->getAppliedTax(
+                    $appliedTaxBuilder,
+                    $unitTaxAfterDiscount * $quantity,
+                    $appliedRate
+                );
+
+                $unitTaxes[] = $unitTaxAfterDiscount;
+                $unitTaxesBeforeDiscount[] = $unitTaxPerRate;
             }
-            $tax = array_sum($taxes);
-            $taxPrice = $price + $tax;
-            $taxSubtotal = $taxPrice * $quantity;
+            $unitTax = array_sum($unitTaxes);
+            $unitTaxBeforeDiscount = array_sum($unitTaxesBeforeDiscount);
+            $rowTax = $unitTax * $quantity;
+            $priceInclTax = $price + $unitTaxBeforeDiscount;
+            $rowTotalInclTax = $priceInclTax * $quantity;
         }
 
-        $this->taxDetailsItemBuilder->setRowTax($tax * $quantity);
+        $this->taxDetailsItemBuilder->setCode($item->getCode());
+        $this->taxDetailsItemBuilder->setRowTax($rowTax);
         $this->taxDetailsItemBuilder->setPrice($price);
-        $this->taxDetailsItemBuilder->setPriceInclTax($taxPrice);
-        $this->taxDetailsItemBuilder->setRowTotal($subtotal);
-        $this->taxDetailsItemBuilder->setTaxableAmount($taxable);
+        $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax);
+        $this->taxDetailsItemBuilder->setRowTotal($rowTotal);
+        $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax);
         $this->taxDetailsItemBuilder->setCode($item->getCode());
         $this->taxDetailsItemBuilder->setType($item->getType());
         $this->taxDetailsItemBuilder->setTaxPercent($rate);
+        $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount);
 
+        $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes);
         return $this->taxDetailsItemBuilder->create();
     }
 
     /**
-     * Calculate item price and row total including/excluding tax based on row total price rounding level
+     * Create AppliedTax data object based applied tax rates and tax amount
      *
-     * @param QuoteDetailsItem $item
-     * @param \Magento\Framework\Object $taxRequest
-     * @param int $storeId
-     * @return TaxDetailsItem
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder $appliedTaxBuilder
+     * @param float $rowTax
+     * @param array $appliedRate
+     * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax
      */
-    protected function rowBaseCalculation(
-        QuoteDetailsItem $item,
-        \Magento\Framework\Object $taxRequest,
-        $storeId
-    ) {
-        $taxRequest->setProductClassId($item->getTaxClassId());
-        $storeRate = $this->calculator->getStoreRate($taxRequest, $storeId);
-        $rate = $this->calculator->getRate($taxRequest);
-        $quantity = $this->getTotalQuantity($item);
-        $price = $this->calculator->round($item->getUnitPrice());
-        $subtotal = $this->calcRowTotal($item);
+    protected function getAppliedTax($appliedTaxBuilder, $rowTax, $appliedRate)
+    {
+        $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder();
+        $appliedTaxBuilder->setAmount($rowTax);
+        $appliedTaxBuilder->setPercent($appliedRate['percent']);
+        $appliedTaxBuilder->setTaxRateKey($appliedRate['id']);
+
+        /** @var  AppliedTaxRate[] $rateDataObjects */
+        $rateDataObjects = [];
+        foreach ($appliedRate['rates'] as $rate) {
+            $appliedTaxRateBuilder->setPercent($rate['percent']);
+            $appliedTaxRateBuilder->setCode($rate['code']);
+            $appliedTaxRateBuilder->setTitle($rate['title']);
+            //Skipped position, priority and rule_id
+            $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create();
+        }
+        $appliedTaxBuilder->setRates($rateDataObjects);
+        $appliedTax = $appliedTaxBuilder->create();
+        return $appliedTax;
+    }
 
-        if ($item->getTaxIncluded()) {
-            if ($taxRequest->getSameRateAsStore() || ($rate == $storeRate)) {
-                $taxable = $subtotal;
-                $rowTax = $this->calculator->calcTaxAmount($taxable, $rate, true, true);
-                $taxPrice = $price;
-                $taxSubtotal = $subtotal;
-                $subtotal = $this->calculator->round($subtotal - $rowTax);
-                $price = $this->calculator->round($subtotal / $quantity);
-            } else {
-                $taxPrice = $this->calculatePriceInclTax($price, $storeRate, $rate);
-                $tax = $this->calculator->calcTaxAmount($taxPrice, $rate, true, true);
-                $price = $taxPrice - $tax;
-                $taxable = $taxPrice * $quantity;
-                $taxSubtotal = $taxPrice * $quantity;
-                $rowTax = $this->calculator->calcTaxAmount($taxable, $rate, true, true);
-                $subtotal = $taxSubtotal - $rowTax;
+    /**
+     * Create AppliedTax data object based on applied tax rates and tax amount
+     *
+     * @param \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTaxBuilder $appliedTaxBuilder
+     * @param float $rowTax
+     * @param float $totalTaxRate
+     * @param array $appliedRates May contain multiple tax rates when catalog price includes tax
+     * @return \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[]
+     */
+    protected function getAppliedTaxes($appliedTaxBuilder, $rowTax, $totalTaxRate, $appliedRates)
+    {
+        /** @var \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */
+        $appliedTaxes = [];
+        $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder();
+        $totalAppliedAmount = 0;
+        foreach ($appliedRates as $appliedRate) {
+            if ($appliedRate['percent'] == 0) {
+                continue;
             }
-        } else {
-            $taxable = $subtotal;
-            $appliedRates = $this->calculator->getAppliedRates($taxRequest);
-            $rowTaxes = [];
-            foreach ($appliedRates as $appliedRate) {
-                $taxRate = $appliedRate['percent'];
-                $rowTaxes[] = $this->calculator->calcTaxAmount($taxable, $taxRate, false, true);
+
+            $appliedAmount = $rowTax / $totalTaxRate * $appliedRate['percent'];
+            //Use delta rounding to split tax amounts for each tax rates between items
+            $appliedAmount = $this->deltaRound(
+                $appliedAmount,
+                $appliedRate['id'],
+                true,
+                self::KEY_APPLIED_TAX_DELTA_ROUNDING
+            );
+            if ($totalAppliedAmount + $appliedAmount > $rowTax) {
+                $appliedAmount = $rowTax - $totalAppliedAmount;
             }
-            $rowTax = array_sum($rowTaxes);
-            $taxSubtotal = $subtotal + $rowTax;
-            $taxPrice = $this->calculator->round($taxSubtotal / $quantity);
+            $totalAppliedAmount += $appliedAmount;
+
+            $appliedTaxBuilder->setAmount($appliedAmount);
+            $appliedTaxBuilder->setPercent($appliedRate['percent']);
+            $appliedTaxBuilder->setTaxRateKey($appliedRate['id']);
+
+            /** @var  AppliedTaxRate[] $rateDataObjects */
+            $rateDataObjects = [];
+            foreach ($appliedRate['rates'] as $rate) {
+                $appliedTaxRateBuilder->setPercent($rate['percent']);
+                $appliedTaxRateBuilder->setCode($rate['code']);
+                $appliedTaxRateBuilder->setTitle($rate['title']);
+                //Skipped position, priority and rule_id
+                $rateDataObjects[$rate['code']] = $appliedTaxRateBuilder->create();
+            }
+            $appliedTaxBuilder->setRates($rateDataObjects);
+            $appliedTax = $appliedTaxBuilder->create();
+            $appliedTaxes[$appliedTax->getTaxRateKey()] = $appliedTax;
         }
 
-        $this->taxDetailsItemBuilder->setPrice($price);
-        $this->taxDetailsItemBuilder->setPriceInclTax($taxPrice);
-        $this->taxDetailsItemBuilder->setRowTotal($subtotal);
-        $this->taxDetailsItemBuilder->setTaxableAmount($taxable);
-        $this->taxDetailsItemBuilder->setCode($item->getCode());
-        $this->taxDetailsItemBuilder->setType($item->getType());
-        $this->taxDetailsItemBuilder->setTaxPercent($rate);
-        $this->taxDetailsItemBuilder->setRowTax($rowTax);
-
-        return $this->taxDetailsItemBuilder->create();
+        return $appliedTaxes;
     }
 
     /**
      * Calculate item price and row total including/excluding tax based on total price rounding level
      *
      * @param QuoteDetailsItem $item
-     * @param \Magento\Framework\Object $taxRequest
+     * @param \Magento\Framework\Object $taxRateRequest
      * @param int $storeId
      * @return TaxDetailsItem
      */
     protected function totalBaseCalculation(
         QuoteDetailsItem $item,
-        \Magento\Framework\Object $taxRequest,
+        \Magento\Framework\Object $taxRateRequest,
         $storeId
     ) {
-        $taxRequest->setProductClassId($item->getTaxClassId());
-        $storeRate = $this->calculator->getStoreRate($taxRequest, $storeId);
-        $rate = $this->calculator->getRate($taxRequest);
+        /** @var  \Magento\Tax\Service\V1\Data\TaxDetails\AppliedTax[] $appliedTaxes */
+        $appliedTaxes = [];
+        $appliedTaxBuilder = $this->taxDetailsItemBuilder->getAppliedTaxBuilder();
+        $appliedTaxRateBuilder = $appliedTaxBuilder->getAppliedTaxRateBuilder();
+
+        $taxRateRequest->setProductClassId($item->getTaxClassId());
+        $appliedRates = $this->calculator->getAppliedRates($taxRateRequest);
+        $rate = $this->calculator->getRate($taxRateRequest);
+
         $quantity = $this->getTotalQuantity($item);
-        $price = $this->calculator->round($item->getUnitPrice());
-        $subtotal = $taxSubtotal = $this->calcRowTotal($item);
+        $price = $priceInclTax = $this->calculator->round($item->getUnitPrice());
+        $rowTotal = $rowTotalInclTax = $taxableAmount = $this->calcRowTotal($item);
 
-        if ($item->getTaxIncluded()) {
-            if ($taxRequest->getSameRateAsStore() || ($rate == $storeRate)) {
-                $taxable = $subtotal;
-                $rowTaxExact = $this->calculator->calcTaxAmount($taxable, $rate, true, false);
-                $rowTax = $this->deltaRound($rowTaxExact, $rate, true);
-                $subtotal = $subtotal - $rowTax;
-                $taxPrice = $price;
-                $price = $this->calculator->round($subtotal / $quantity);
+        $discountAmount = $item->getDiscountAmount();
+        $applyTaxAfterDiscount = $this->config->applyTaxAfterDiscount($storeId);
+
+        $discountTaxCompensationAmount = 0;
 
+        $isTotalBasedCalculation = ($this->config->getAlgorithm($storeId) == Calculation::CALC_TOTAL_BASE);
+
+        if ($item->getTaxIncluded()) {
+            if ($taxRateRequest->getSameRateAsStore()) {
+                $rowTaxExact = $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, false);
+                if ($isTotalBasedCalculation) {
+                    $rowTax = $this->deltaRound($rowTaxExact, $rate, true);
+                } else {
+                    $rowTax = $this->calculator->round($rowTaxExact);
+                }
+                $rowTotal = $rowTotalInclTax - $rowTax;
+                $price = $this->calculator->round($rowTotal / $quantity);
             } else {
-                $taxPrice = $this->calculatePriceInclTax($price, $storeRate, $rate);
-                $tax = $this->calculator->calcTaxAmount($taxPrice, $rate, true, true);
-                $price = $taxPrice - $tax;
-                $taxSubtotal = $taxable = $taxPrice * $quantity;
-                $rowTax =
-                    $this->deltaRound($this->calculator->calcTaxAmount($taxable, $rate, true, false), $rate, true);
-                $subtotal = $taxSubtotal - $rowTax;
+                $storeRate = $this->calculator->getStoreRate($taxRateRequest, $storeId);
+                $priceInclTax = $this->calculatePriceInclTax($price, $storeRate, $rate);
+                $rowTotalInclTax = $priceInclTax * $quantity;
+                $taxableAmount = $rowTotalInclTax;
+                if ($isTotalBasedCalculation) {
+                    $rowTax = $this->deltaRound(
+                        $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, false),
+                        $rate,
+                        true
+                    );
+                } else {
+                    $rowTax = $this->calculator->calcTaxAmount($rowTotalInclTax, $rate, true, true);
+                }
+                $rowTotal = $rowTotalInclTax - $rowTax;
+                $price = $this->calculator->round($rowTotal / $quantity);
             }
-        } else {
-            $taxable = $subtotal;
-            $appliedRates = $this->calculator->getAppliedRates($taxRequest);
+
+            //Handle discount
+            if ($discountAmount && $applyTaxAfterDiscount) {
+                //TODO: handle originalDiscountAmount
+                $taxableAmount = max($taxableAmount - $discountAmount, 0);
+                $rowTaxAfterDiscount = $this->calculator->calcTaxAmount(
+                    $taxableAmount,
+                    $rate,
+                    true,
+                    false
+                );
+                if ($isTotalBasedCalculation) {
+                    //Round the row tax using a different type so that we don't pollute the rounding deltas
+                    $rowTaxAfterDiscount = $this->deltaRound(
+                        $rowTaxAfterDiscount,
+                        $rate,
+                        true,
+                        self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING
+                    );
+                } else {
+                    $rowTaxAfterDiscount = $this->calculator->round($rowTaxAfterDiscount);
+                }
+
+                // Set discount tax compensation
+                $discountTaxCompensationAmount = $rowTax - $rowTaxAfterDiscount;
+                $rowTax = $rowTaxAfterDiscount;
+            }
+
+            //save applied taxes
+            $appliedTaxes = $this->getAppliedTaxes(
+                $appliedTaxBuilder,
+                $rowTax,
+                $rate,
+                $appliedRates
+            );
+        } else { //catalog price does not include tax
+            $appliedRates = $this->calculator->getAppliedRates($taxRateRequest);
             $rowTaxes = [];
+            $rowTaxesBeforeDiscount = [];
+            //Apply each tax rate separately
             foreach ($appliedRates as $appliedRate) {
                 $taxId = $appliedRate['id'];
                 $taxRate = $appliedRate['percent'];
-                $rowTaxes[] = $this->deltaRound(
-                    $this->calculator->calcTaxAmount($taxable, $taxRate, false, false),
-                    $taxId,
-                    false
+                if ($isTotalBasedCalculation) {
+                    $rowTaxPerRate = $this->deltaRound(
+                        $this->calculator->calcTaxAmount($rowTotal, $taxRate, false, false),
+                        $taxId,
+                        false
+                    );
+                } else {
+                    $rowTaxPerRate = $this->calculator->calcTaxAmount($rowTotal, $taxRate, false, true);
+                }
+                $rowTaxAfterDiscount = $rowTaxPerRate;
+                //Handle discount
+                if ($discountAmount && $applyTaxAfterDiscount) {
+                    //TODO: handle originalDiscountAmount
+                    $rowTaxAfterDiscount = $this->calculator->calcTaxAmount(
+                        max($rowTotal - $discountAmount, 0),
+                        $taxRate,
+                        false,
+                        false
+                    );
+                    if ($isTotalBasedCalculation) {
+                        //Round the row tax using a different type so that we don't pollute the rounding deltas
+                        $rowTaxAfterDiscount = $this->deltaRound(
+                            $rowTaxAfterDiscount,
+                            $taxRate,
+                            false,
+                            self::KEY_TAX_AFTER_DISCOUNT_DELTA_ROUNDING
+                        );
+                    } else {
+                        $rowTaxAfterDiscount = $this->calculator->round($rowTaxAfterDiscount);
+                    }
+                }
+                $appliedTaxes[$appliedRate['id']] = $this->getAppliedTax(
+                    $appliedTaxBuilder,
+                    $rowTaxAfterDiscount,
+                    $appliedRate
                 );
+                $rowTaxes[] = $rowTaxAfterDiscount;
+                $rowTaxesBeforeDiscount[] = $rowTaxPerRate;
             }
             $rowTax = array_sum($rowTaxes);
-            $taxSubtotal = $subtotal + $rowTax;
-            $taxPrice = $this->calculator->round($taxSubtotal / $quantity);
+            $rowTaxBeforeDiscount = array_sum($rowTaxesBeforeDiscount);
+            $rowTotalInclTax = $rowTotal + $rowTaxBeforeDiscount;
+            $priceInclTax = $this->calculator->round($rowTotalInclTax / $quantity);
         }
 
+        $this->taxDetailsItemBuilder->setCode($item->getCode());
         $this->taxDetailsItemBuilder->setRowTax($rowTax);
         $this->taxDetailsItemBuilder->setPrice($price);
-        $this->taxDetailsItemBuilder->setPriceInclTax($taxPrice);
-        $this->taxDetailsItemBuilder->setRowTotal($subtotal);
-        $this->taxDetailsItemBuilder->setTaxableAmount($taxable);
+        $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax);
+        $this->taxDetailsItemBuilder->setRowTotal($rowTotal);
+        $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax);
         $this->taxDetailsItemBuilder->setCode($item->getCode());
         $this->taxDetailsItemBuilder->setType($item->getType());
         $this->taxDetailsItemBuilder->setTaxPercent($rate);
+        $this->taxDetailsItemBuilder->setDiscountTaxCompensationAmount($discountTaxCompensationAmount);
 
+        $this->taxDetailsItemBuilder->setAppliedTaxes($appliedTaxes);
         return $this->taxDetailsItemBuilder->create();
     }
 
@@ -459,15 +725,15 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      * @param string $type
      * @return float
      */
-    protected function deltaRound($price, $rate, $direction, $type = 'regular')
+    protected function deltaRound($price, $rate, $direction, $type = self::KEY_REGULAR_DELTA_ROUNDING)
     {
         if ($price) {
             $rate = (string)$rate;
             $type = $type . $direction;
             // initialize the delta to a small number to avoid non-deterministic behavior with rounding of 0.5
-            $delta = isset($this->roundingDeltas[$type][$rate]) ?
-                $this->roundingDeltas[$type][$rate] :
-                0.000001;
+            $delta = isset($this->roundingDeltas[$type][$rate])
+                ? $this->roundingDeltas[$type][$rate]
+                : 0.000001;
             $price += $delta;
             $roundPrice = $this->calculator->round($price);
             $this->roundingDeltas[$type][$rate] = $price - $roundPrice;
@@ -486,24 +752,25 @@ class TaxCalculationService implements TaxCalculationServiceInterface
     protected function calculateParent($children, $quantity)
     {
         $rowTotal = 0.00;
+        $rowTotalInclTax = 0.00;
         $rowTax = 0.00;
         $taxableAmount = 0.00;
 
         foreach ($children as $child) {
             $rowTotal += $child->getRowTotal();
+            $rowTotalInclTax += $child->getRowTotalInclTax();
             $rowTax += $child->getRowTax();
             $taxableAmount += $child->getTaxableAmount();
         }
 
-        $rowTotalInclTax = $rowTotal + $rowTax;
         $price = $this->calculator->round($rowTotal / $quantity);
         $priceInclTax = $this->calculator->round($rowTotalInclTax / $quantity);
 
         $this->taxDetailsItemBuilder->setPrice($price);
         $this->taxDetailsItemBuilder->setPriceInclTax($priceInclTax);
         $this->taxDetailsItemBuilder->setRowTotal($rowTotal);
+        $this->taxDetailsItemBuilder->setRowTotalInclTax($rowTotalInclTax);
         $this->taxDetailsItemBuilder->setRowTax($rowTax);
-        $this->taxDetailsItemBuilder->setTaxableAmount($taxableAmount);
 
         return $this->taxDetailsItemBuilder;
     }
@@ -533,7 +800,7 @@ class TaxCalculationService implements TaxCalculationServiceInterface
      * @param TaxDetailsItem $item
      * @return array
      */
-    protected function addSubtotalAmount($taxDetailsData, TaxDetailsItem $item)
+    protected function aggregateItemData($taxDetailsData, TaxDetailsItem $item)
     {
         $taxDetailsData[TaxDetails::KEY_SUBTOTAL]
             = $taxDetailsData[TaxDetails::KEY_SUBTOTAL] + $item->getRowTotal();
@@ -541,9 +808,39 @@ class TaxCalculationService implements TaxCalculationServiceInterface
         $taxDetailsData[TaxDetails::KEY_TAX_AMOUNT]
             = $taxDetailsData[TaxDetails::KEY_TAX_AMOUNT] + $item->getRowTax();
 
-        $taxDetailsData[TaxDetails::KEY_DISCOUNT_AMOUNT]
-            = $taxDetailsData[TaxDetails::KEY_DISCOUNT_AMOUNT] + $item->getDiscountAmount();
+        $taxDetailsData[TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT] =
+            $taxDetailsData[TaxDetails::KEY_DISCOUNT_TAX_COMPENSATION_AMOUNT]
+            + $item->getDiscountTaxCompensationAmount();
+
+        $itemAppliedTaxes = $item->getAppliedTaxes();
+        if (!isset($taxDetailsData[TaxDetails::KEY_APPLIED_TAXES])) {
+            $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES] = [];
+        }
+        $appliedTaxes = $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES];
+        foreach ($itemAppliedTaxes as $taxId => $itemAppliedTax) {
+            if (!isset($appliedTaxes[$taxId])) {
+                //convert rate data object to array
+                $rates = [];
+                $rateDataObjects = $itemAppliedTax->getRates();
+                foreach ($rateDataObjects as $rateDataObject) {
+                    $rates[$rateDataObject->getCode()] = [
+                        AppliedTaxRate::KEY_CODE => $rateDataObject->getCode(),
+                        AppliedTaxRate::KEY_TITLE => $rateDataObject->getTitle(),
+                        AppliedTaxRate::KEY_PERCENT => $rateDataObject->getPercent(),
+                    ];
+                }
+                $appliedTaxes[$taxId] = [
+                    AppliedTax::KEY_AMOUNT => $itemAppliedTax->getAmount(),
+                    AppliedTax::KEY_PERCENT => $itemAppliedTax->getPercent(),
+                    AppliedTax::KEY_RATES => $rates,
+                    AppliedTax::KEY_TAX_RATE_KEY => $itemAppliedTax->getTaxRateKey(),
+                ];
+            } else {
+                $appliedTaxes[$taxId][AppliedTax::KEY_AMOUNT] += $itemAppliedTax->getAmount();
+            }
+        }
 
+        $taxDetailsData[TaxDetails::KEY_APPLIED_TAXES] = $appliedTaxes;
         return $taxDetailsData;
     }
 
diff --git a/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php
index 9b5bf8a87b4b4dbf89e61be12d52937b9b852f70..1f663e8d179bb96ade6da1188f70e5faaa6fc2a8 100644
--- a/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php
+++ b/app/code/Magento/Tax/Service/V1/TaxCalculationServiceInterface.php
@@ -33,5 +33,25 @@ interface TaxCalculationServiceInterface
      * @param null|int $storeId
      * @return \Magento\Tax\Service\V1\Data\TaxDetails
      */
-    public function calculateTax(\Magento\Tax\Service\V1\Data\QuoteDetails $quoteDetails, $storeId);
+    public function calculateTax(\Magento\Tax\Service\V1\Data\QuoteDetails $quoteDetails, $storeId = null);
+
+    /**
+     * Get default rate request
+     *
+     * @param int $productTaxClassID
+     * @param int $customerId
+     * @param string $storeId
+     * @return float
+     */
+    public function getDefaultCalculatedRate($productTaxClassID, $customerId = null, $storeId = null);
+
+    /**
+     * Get rate request
+     *
+     * @param int $productTaxClassID
+     * @param int $customerId
+     * @param string $storeId
+     * @return float
+     */
+    public function getCalculatedRate($productTaxClassID, $customerId = null, $storeId = null);
 }
diff --git a/app/code/Magento/Tax/Service/V1/TaxClassService.php b/app/code/Magento/Tax/Service/V1/TaxClassService.php
index 003216283d586b1cc906b28ad038069601cad489..fbcd6c71c2865df5005348f758a1e4bd7648fa95 100644
--- a/app/code/Magento/Tax/Service/V1/TaxClassService.php
+++ b/app/code/Magento/Tax/Service/V1/TaxClassService.php
@@ -25,16 +25,16 @@
 namespace Magento\Tax\Service\V1;
 
 use Magento\Framework\Exception\InputException;
-use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Model\Exception as ModelException;
 use Magento\Framework\Service\V1\Data\Search\FilterGroup;
 use Magento\Framework\Service\V1\Data\SearchCriteria;
-use Magento\Tax\Model\ClassModelFactory as TaxClassModelFactory;
+use Magento\Tax\Model\ClassModelRegistry;
 use Magento\Tax\Model\Converter;
 use Magento\Tax\Model\Resource\TaxClass\Collection as TaxClassCollection;
 use Magento\Tax\Model\Resource\TaxClass\CollectionFactory as TaxClassCollectionFactory;
-use Magento\Tax\Service\V1\Data\SearchResultsBuilder;
+use Magento\Tax\Service\V1\Data\TaxClassSearchResultsBuilder;
 use Magento\Tax\Service\V1\Data\TaxClass as TaxClassDataObject;
+use Magento\Framework\Exception\CouldNotDeleteException;
 
 /**
  * Tax class service.
@@ -47,7 +47,7 @@ class TaxClassService implements TaxClassServiceInterface
     protected $taxClassCollectionFactory;
 
     /**
-     * @var SearchResultsBuilder
+     * @var TaxClassSearchResultsBuilder
      */
     protected $searchResultsBuilder;
 
@@ -57,9 +57,9 @@ class TaxClassService implements TaxClassServiceInterface
     protected $converter;
 
     /**
-     * @var TaxClassModelFactory
+     * @var ClassModelRegistry
      */
-    protected $taxClassModelFactory;
+    protected $classModelRegistry;
 
     const CLASS_ID_NOT_ALLOWED = 'class_id is not expected for this request.';
 
@@ -67,20 +67,20 @@ class TaxClassService implements TaxClassServiceInterface
      * Initialize dependencies.
      *
      * @param TaxClassCollectionFactory $taxClassCollectionFactory
-     * @param TaxClassModelFactory $taxClassModelFactory
-     * @param SearchResultsBuilder $searchResultsBuilder
+     * @param TaxClassSearchResultsBuilder $searchResultsBuilder
      * @param Converter $converter
+     * @param ClassModelRegistry $classModelRegistry
      */
     public function __construct(
         TaxClassCollectionFactory $taxClassCollectionFactory,
-        TaxClassModelFactory $taxClassModelFactory,
-        SearchResultsBuilder $searchResultsBuilder,
-        Converter $converter
+        TaxClassSearchResultsBuilder $searchResultsBuilder,
+        Converter $converter,
+        ClassModelRegistry $classModelRegistry
     ) {
         $this->taxClassCollectionFactory = $taxClassCollectionFactory;
-        $this->taxClassModelFactory = $taxClassModelFactory;
         $this->searchResultsBuilder = $searchResultsBuilder;
         $this->converter = $converter;
+        $this->classModelRegistry = $classModelRegistry;
     }
 
     /**
@@ -106,6 +106,7 @@ class TaxClassService implements TaxClassServiceInterface
                 throw $e;
             }
         }
+        $this->classModelRegistry->registerTaxClass($taxModel);
         return $taxModel->getId();
     }
 
@@ -114,10 +115,7 @@ class TaxClassService implements TaxClassServiceInterface
      */
     public function getTaxClass($taxClassId)
     {
-        $taxClassModel = $this->taxClassModelFactory->create()->load($taxClassId);
-        if (!$taxClassModel->getId()) {
-            throw NoSuchEntityException::singleField(TaxClassDataObject::KEY_ID, $taxClassId);
-        }
+        $taxClassModel = $this->classModelRegistry->retrieve($taxClassId);
         return $this->converter->createTaxClassData($taxClassModel);
     }
 
@@ -136,10 +134,7 @@ class TaxClassService implements TaxClassServiceInterface
             throw InputException::invalidFieldValue('taxClassId', $taxClassId);
         }
 
-        $originalTaxClassModel = $this->taxClassModelFactory->create()->load($taxClassId);
-        if (!$originalTaxClassModel->getId()) {
-            throw NoSuchEntityException::singleField('taxClassId', $taxClassId);
-        }
+        $originalTaxClassModel = $this->classModelRegistry->retrieve($taxClassId);
 
         $taxClassModel = $this->converter->createTaxClassModel($taxClass);
         $taxClassModel->setId($taxClassId);
@@ -154,6 +149,7 @@ class TaxClassService implements TaxClassServiceInterface
         } catch (\Exception $e) {
             return false;
         }
+        $this->classModelRegistry->registerTaxClass($taxClassModel);
 
         return true;
     }
@@ -163,16 +159,16 @@ class TaxClassService implements TaxClassServiceInterface
      */
     public function deleteTaxClass($taxClassId)
     {
-        $taxClassModel = $this->taxClassModelFactory->create()->load($taxClassId);
-        if (!$taxClassModel->getId()) {
-            throw NoSuchEntityException::singleField('taxClassId', $taxClassId);
-        }
+        $taxClassModel = $this->classModelRegistry->retrieve($taxClassId);
 
         try {
             $taxClassModel->delete();
+        } catch (CouldNotDeleteException $e) {
+            throw $e;
         } catch (\Exception $e) {
             return false;
         }
+        $this->classModelRegistry->remove($taxClassId);
 
         return true;
     }
@@ -195,8 +191,8 @@ class TaxClassService implements TaxClassServiceInterface
         $classType = $taxClass->getClassType();
         if (!\Zend_Validate::is(trim($classType), 'NotEmpty')) {
             $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => TaxClassDataObject::KEY_TYPE]);
-        } else if ($classType !== TaxClassDataObject::TYPE_CUSTOMER
-            && $classType !== TaxClassDataObject::TYPE_PRODUCT
+        } else if ($classType !== TaxClassServiceInterface::TYPE_CUSTOMER
+            && $classType !== TaxClassServiceInterface::TYPE_PRODUCT
         ) {
             $exception->addError(
                 InputException::INVALID_FIELD_VALUE,
@@ -213,7 +209,7 @@ class TaxClassService implements TaxClassServiceInterface
      * Retrieve tax classes which match a specific criteria.
      *
      * @param \Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria
-     * @return \Magento\Tax\Service\V1\Data\SearchResults containing Data\TaxClass
+     * @return \Magento\Tax\Service\V1\Data\TaxClassSearchResults containing Data\TaxClass
      * @throws \Magento\Framework\Exception\InputException
      */
     public function searchTaxClass(\Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria)
diff --git a/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php
index 4a3617407e5a68591d406e1a5cd7740e7ae7e190..4a1b4e48f5e5015ff33dbc90d5cbf601d6c9a17b 100644
--- a/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php
+++ b/app/code/Magento/Tax/Service/V1/TaxClassServiceInterface.php
@@ -29,6 +29,13 @@ namespace Magento\Tax\Service\V1;
  */
 interface TaxClassServiceInterface
 {
+    /**#@+
+     * Tax class type.
+     */
+    const TYPE_CUSTOMER = 'CUSTOMER';
+    const TYPE_PRODUCT = 'PRODUCT';
+    /**#@-*/
+
     /**
      * Create a Tax Class
      *
@@ -65,6 +72,7 @@ interface TaxClassServiceInterface
      * @param int $taxClassId
      * @return bool True if the tax class was deleted, false otherwise
      * @throws \Magento\Framework\Exception\NoSuchEntityException If tax class with $taxClassId does not exist
+     * @throws \Magento\Framework\Exception\CouldNotDeleteException
      */
     public function deleteTaxClass($taxClassId);
 
@@ -72,7 +80,7 @@ interface TaxClassServiceInterface
      * Retrieve tax classes which match a specific criteria.
      *
      * @param \Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria
-     * @return \Magento\Tax\Service\V1\Data\SearchResults containing Data\TaxClass
+     * @return \Magento\Tax\Service\V1\Data\TaxClassSearchResults containing Data\TaxClass
      * @throws \Magento\Framework\Exception\InputException
      */
     public function searchTaxClass(\Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria);
diff --git a/app/code/Magento/Tax/Service/V1/TaxRateService.php b/app/code/Magento/Tax/Service/V1/TaxRateService.php
index b5c9e32d78e38e5c99ba671c5c8f4fbc3b21f7f4..8c35f798926f1a645df2326f75da370941574d50 100644
--- a/app/code/Magento/Tax/Service/V1/TaxRateService.php
+++ b/app/code/Magento/Tax/Service/V1/TaxRateService.php
@@ -27,9 +27,13 @@ namespace Magento\Tax\Service\V1;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Model\Exception as ModelException;
 use Magento\Tax\Model\Calculation\Rate\Converter;
+use Magento\Tax\Model\Calculation\RateFactory;
+use Magento\Tax\Service\V1\Data\TaxRate as TaxRateDataObject;
 use Magento\Tax\Model\Calculation\Rate as RateModel;
 use Magento\Tax\Model\Calculation\RateRegistry;
-use Magento\Tax\Service\V1\Data\TaxRate as TaxRateDataObject;
+use Magento\Framework\Service\V1\Data\SearchCriteria;
+use Magento\Tax\Model\Resource\Calculation\Rate\Collection;
+use Magento\Framework\Service\V1\Data\Search\FilterGroup;
 use Magento\Tax\Service\V1\Data\TaxRateBuilder;
 
 /**
@@ -59,21 +63,37 @@ class TaxRateService implements TaxRateServiceInterface
      */
     protected $rateRegistry;
 
+    /**
+     * @var Data\TaxRateSearchResultsBuilder
+     */
+    private $taxRateSearchResultsBuilder;
+
+    /**
+     * @var RateFactory
+     */
+    private $rateFactory;
+
     /**
      * Constructor
      *
      * @param TaxRateBuilder $rateBuilder
      * @param Converter $converter
      * @param RateRegistry $rateRegistry
+     * @param Data\TaxRateSearchResultsBuilder $taxRateSearchResultsBuilder
+     * @param RateFactory $rateFactory
      */
     public function __construct(
         TaxRateBuilder $rateBuilder,
         Converter $converter,
-        RateRegistry $rateRegistry
+        RateRegistry $rateRegistry,
+        Data\TaxRateSearchResultsBuilder $taxRateSearchResultsBuilder,
+        RateFactory $rateFactory
     ) {
         $this->rateBuilder = $rateBuilder;
         $this->converter = $converter;
         $this->rateRegistry = $rateRegistry;
+        $this->taxRateSearchResultsBuilder = $taxRateSearchResultsBuilder;
+        $this->rateFactory = $rateFactory;
     }
 
     /**
@@ -118,6 +138,43 @@ class TaxRateService implements TaxRateServiceInterface
         return true;
     }
 
+    /**
+     * {@inheritdoc}
+     */
+    public function searchTaxRates(SearchCriteria $searchCriteria)
+    {
+        /** @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection */
+        $collection = $this->rateFactory->create()->getCollection();
+        $collection->joinRegionTable();
+
+        //Add filters from root filter group to the collection
+        foreach ($searchCriteria->getFilterGroups() as $group) {
+            $this->addFilterGroupToCollection($group, $collection);
+        }
+
+        $sortOrders = $searchCriteria->getSortOrders();
+        if ($sortOrders) {
+            foreach ($sortOrders as $field => $direction) {
+                $collection->addOrder($field, $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC');
+            }
+        }
+        $collection->setCurPage($searchCriteria->getCurrentPage());
+        $collection->setPageSize($searchCriteria->getPageSize());
+
+        $taxRate = [];
+
+        /** @var \Magento\Tax\Model\Calculation\Rate $taxRateModel */
+        foreach ($collection as $taxRateModel) {
+            $taxRate[] = $this->converter->createTaxRateDataObjectFromModel($taxRateModel);
+        }
+
+        return $this->taxRateSearchResultsBuilder
+            ->setItems($taxRate)
+            ->setTotalCount($collection->getSize())
+            ->setSearchCriteria($searchCriteria)
+            ->create();
+    }
+
     /**
      * Save Tax Rate
      *
@@ -130,8 +187,10 @@ class TaxRateService implements TaxRateServiceInterface
     {
         $this->validate($taxRate);
         $taxRateModel = $this->converter->createTaxRateModel($taxRate);
+        $taxRateTitles = $this->converter->createTitleArrayFromServiceObject($taxRate);
         try {
             $taxRateModel->save();
+            $taxRateModel->saveTitles($taxRateTitles);
         } catch (ModelException $e) {
             if ($e->getCode() == ModelException::ERROR_CODE_ENTITY_ALREADY_EXISTS) {
                 throw new InputException($e->getMessage());
@@ -143,6 +202,50 @@ class TaxRateService implements TaxRateServiceInterface
         return $taxRateModel;
     }
 
+    /**
+     * Helper function that adds a FilterGroup to the collection.
+     *
+     * @param FilterGroup $filterGroup
+     * @param Collection $collection
+     * @return void
+     * @throws \Magento\Framework\Exception\InputException
+     */
+    protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection)
+    {
+        $fields = [];
+        $conditions = [];
+        foreach ($filterGroup->getFilters() as $filter) {
+            $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
+            $fields[] = $this->translateField($filter->getField());
+            $conditions[] = [$condition => $filter->getValue()];
+        }
+        if ($fields) {
+            $collection->addFieldToFilter($fields, $conditions);
+        }
+    }
+
+    /**
+     * Translates a field name to a DB column name for use in collection queries.
+     *
+     * @param string $field a field name that should be translated to a DB column name.
+     * @return string
+     */
+    protected function translateField($field)
+    {
+        switch ($field) {
+            case TaxRateDataObject::KEY_POSTCODE:
+            case TaxRateDataObject::KEY_COUNTRY_ID:
+            case TaxRateDataObject::KEY_REGION_ID:
+                return 'tax_' . $field;
+            case TaxRateDataObject::KEY_PERCENTAGE_RATE:
+                return 'rate';
+            case TaxRateDataObject::KEY_REGION_NAME:
+                return 'region_table.code';
+            default:
+                return "main_table." . $field;
+        }
+    }
+
     /**
      * Validate tax rate
      *
@@ -159,9 +262,6 @@ class TaxRateService implements TaxRateServiceInterface
         if (!\Zend_Validate::is(trim($taxRate->getCountryId()), 'NotEmpty')) {
             $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => 'country_id']);
         }
-        if (!\Zend_Validate::is(trim($taxRate->getRegionId()), 'NotEmpty')) {
-            $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => 'region_id']);
-        }
         if (!\Zend_Validate::is(trim($taxRate->getPercentageRate()), 'NotEmpty')) {
             $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => 'percentage_rate']);
         }
@@ -186,10 +286,6 @@ class TaxRateService implements TaxRateServiceInterface
                 $exception->addError('Range To should be equal or greater than Range From.');
             }
 
-        } else {
-            if (!\Zend_Validate::is(trim($taxRate->getPostcode()), 'NotEmpty')) {
-                $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => 'postcode']);
-            }
         }
         if ($exception->wasErrorAdded()) {
             throw $exception;
diff --git a/app/code/Magento/Tax/Service/V1/TaxRateServiceInterface.php b/app/code/Magento/Tax/Service/V1/TaxRateServiceInterface.php
index 23d0c3e575ed8b55ebaf48081ffa29d0b726d627..6d123f0a17b9633a5f18af615d0508de35ad8bee 100644
--- a/app/code/Magento/Tax/Service/V1/TaxRateServiceInterface.php
+++ b/app/code/Magento/Tax/Service/V1/TaxRateServiceInterface.php
@@ -65,4 +65,13 @@ interface TaxRateServiceInterface
      * @throws \Exception If something went wrong while performing the delete.
      */
     public function deleteTaxRate($rateId);
+
+    /**
+     * Search TaxRates
+     *
+     * @param \Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria
+     * @return \Magento\Tax\Service\V1\Data\TaxRateSearchResults containing Data\TaxRate objects
+     * @throws \Magento\Framework\Exception\InputException If there is a problem with the input
+     */
+    public function searchTaxRates(\Magento\Framework\Service\V1\Data\SearchCriteria $searchCriteria);
 }
diff --git a/app/code/Magento/Tax/Service/V1/TaxRuleService.php b/app/code/Magento/Tax/Service/V1/TaxRuleService.php
index c8f0033c72fb78de2becb652b893d8a98cd3b35c..22f85d053c3df79b863d2b2c19eb958c28dd1323 100644
--- a/app/code/Magento/Tax/Service/V1/TaxRuleService.php
+++ b/app/code/Magento/Tax/Service/V1/TaxRuleService.php
@@ -26,13 +26,19 @@ namespace Magento\Tax\Service\V1;
 
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Service\V1\Data\SearchCriteria;
-use Magento\Tax\Model\Calculation\Rule as TaxRuleModel;
+use Magento\Framework\Service\V1\Data\Search\FilterGroup;
 use Magento\Tax\Model\Calculation\TaxRuleConverter;
 use Magento\Tax\Model\Calculation\TaxRuleRegistry;
 use Magento\Tax\Service\V1\Data\TaxRule;
 use Magento\Tax\Service\V1\Data\TaxRuleBuilder;
+use Magento\Tax\Model\Calculation\Rule as TaxRuleModel;
+use Magento\Tax\Model\Calculation\RuleFactory as TaxRuleModelFactory;
+use Magento\Tax\Model\Resource\Calculation\Rule\Collection;
 use Magento\Framework\Model\Exception as ModelException;
 
+/**
+ * TaxRuleService implementation.
+ */
 class TaxRuleService implements TaxRuleServiceInterface
 {
     /**
@@ -52,19 +58,35 @@ class TaxRuleService implements TaxRuleServiceInterface
      */
     protected $taxRuleRegistry;
 
+    /**
+     * @var Data\TaxRuleSearchResultsBuilder
+     */
+    protected $taxRuleSearchResultsBuilder;
+
+    /**
+     * @var TaxRuleModelFactory
+     */
+    protected $taxRuleModelFactory;
+
     /**
      * @param TaxRuleBuilder $taxRuleBuilder
      * @param TaxRuleConverter $converter
      * @param TaxRuleRegistry $taxRuleRegistry
+     * @param Data\TaxRuleSearchResultsBuilder $taxRuleSearchResultsBuilder
+     * @param TaxRuleModelFactory $taxRuleModelFactory
      */
     public function __construct(
         TaxRuleBuilder $taxRuleBuilder,
         TaxRuleConverter $converter,
-        TaxRuleRegistry $taxRuleRegistry
+        TaxRuleRegistry $taxRuleRegistry,
+        Data\TaxRuleSearchResultsBuilder $taxRuleSearchResultsBuilder,
+        TaxRuleModelFactory $taxRuleModelFactory
     ) {
         $this->taxRuleBuilder = $taxRuleBuilder;
         $this->converter = $converter;
         $this->taxRuleRegistry = $taxRuleRegistry;
+        $this->taxRuleSearchResultsBuilder = $taxRuleSearchResultsBuilder;
+        $this->taxRuleModelFactory = $taxRuleModelFactory;
     }
 
     /**
@@ -114,7 +136,87 @@ class TaxRuleService implements TaxRuleServiceInterface
      */
     public function searchTaxRules(SearchCriteria $searchCriteria)
     {
-        // TODO: Implement searchTaxRules() method.
+        $this->taxRuleSearchResultsBuilder->setSearchCriteria($searchCriteria);
+        $collection = $this->taxRuleModelFactory->create()->getCollection();
+
+        //Add filters from root filter group to the collection
+        foreach ($searchCriteria->getFilterGroups() as $group) {
+            $this->addFilterGroupToCollection($group, $collection);
+        }
+        $this->taxRuleSearchResultsBuilder->setTotalCount($collection->getSize());
+        $sortOrders = $searchCriteria->getSortOrders();
+        if ($sortOrders) {
+            foreach ($sortOrders as $field => $direction) {
+                $field = $this->translateField($field);
+                $collection->addOrder($field, $direction == SearchCriteria::SORT_ASC ? 'ASC' : 'DESC');
+            }
+        }
+        $collection->setCurPage($searchCriteria->getCurrentPage());
+        $collection->setPageSize($searchCriteria->getPageSize());
+
+        $taxRules = [];
+
+        /** @var TaxRuleModel $taxRuleModel */
+        foreach ($collection as $taxRuleModel) {
+            $taxRule = $this->converter->createTaxRuleDataObjectFromModel($taxRuleModel);
+            $taxRules[] = $taxRule;
+        }
+        $this->taxRuleSearchResultsBuilder->setItems($taxRules);
+        return $this->taxRuleSearchResultsBuilder->create();
+    }
+
+    /**
+     * Helper function that adds a FilterGroup to the collection.
+     *
+     * @param FilterGroup $filterGroup
+     * @param Collection $collection
+     * @return void
+     * @throws \Magento\Framework\Exception\InputException
+     */
+    protected function addFilterGroupToCollection(FilterGroup $filterGroup, Collection $collection)
+    {
+        $fields = [];
+        $conditions = [];
+        foreach ($filterGroup->getFilters() as $filter) {
+            $condition = $filter->getConditionType() ? $filter->getConditionType() : 'eq';
+            $field = $this->translateField($filter->getField());
+            $fields[] = $field;
+            $conditions[] = [$condition => $filter->getValue()];
+            switch ($field) {
+                case 'rate.tax_calculation_rate_id':
+                    $collection->joinCalculationData('rate');
+                    break;
+
+                case 'ctc.customer_tax_class_id':
+                    $collection->joinCalculationData('ctc');
+                    break;
+
+                case 'ptc.product_tax_class_id':
+                    $collection->joinCalculationData('ptc');
+                    break;
+            }
+        }
+        if ($fields) {
+            $collection->addFieldToFilter($fields, $conditions);
+        }
+    }
+
+    /**
+     * Translates a field name to a DB column name for use in collection queries.
+     *
+     * @param string $field a field name that should be translated to a DB column name.
+     * @return string
+     */
+    protected function translateField($field)
+    {
+        switch ($field) {
+            case TaxRule::ID:
+                return 'tax_calculation_rule_id';
+            case TaxRule::SORT_ORDER:
+                return 'position';
+            default:
+                return $field;
+        }
     }
 
     /**
@@ -156,10 +258,6 @@ class TaxRuleService implements TaxRuleServiceInterface
     {
         $exception = new InputException();
 
-        // SortOrder is required and must be 0 or greater
-        if (!\Zend_Validate::is(trim($rule->getSortOrder()), 'NotEmpty')) {
-            $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => TaxRule::SORT_ORDER]);
-        }
         if (!\Zend_Validate::is(trim($rule->getSortOrder()), 'GreaterThan', [-1])) {
             $exception->addError(
                 InputException::INVALID_FIELD_MIN_VALUE,
@@ -167,10 +265,6 @@ class TaxRuleService implements TaxRuleServiceInterface
             );
         }
 
-        // Priority is required and must be 0 or greater
-        if (!\Zend_Validate::is(trim($rule->getPriority()), 'NotEmpty')) {
-            $exception->addError(InputException::REQUIRED_FIELD, ['fieldName' => TaxRule::PRIORITY]);
-        }
         if (!\Zend_Validate::is(trim($rule->getPriority()), 'GreaterThan', [-1])) {
             $exception->addError(
                 InputException::INVALID_FIELD_MIN_VALUE,
diff --git a/app/code/Magento/Tax/etc/adminhtml/system.xml b/app/code/Magento/Tax/etc/adminhtml/system.xml
index 0e240d0de7bc7b5f838012e6a4196b8f87223d0e..1188cdce2b2804829be19969a1a8e9f11510137c 100644
--- a/app/code/Magento/Tax/etc/adminhtml/system.xml
+++ b/app/code/Magento/Tax/etc/adminhtml/system.xml
@@ -34,15 +34,15 @@
                 <label>Tax Classes</label>
                 <field id="shipping_tax_class" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
                     <label>Tax Class for Shipping</label>
-                    <source_model>Magento\Tax\Model\Config\Source\TaxClass\Product</source_model>
+                    <source_model>Magento\Tax\Model\TaxClass\Source\Product</source_model>
                 </field>
                 <field id="default_product_tax_class" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
                     <label>Default Tax Class for Product</label>
-                    <source_model>Magento\Tax\Model\Config\Source\TaxClass\Product</source_model>
+                    <source_model>Magento\Tax\Model\TaxClass\Source\Product</source_model>
                 </field>
                 <field id="default_customer_tax_class" translate="label" type="select" sortOrder="30" showInDefault="1" showInWebsite="0" showInStore="0">
                     <label>Default Tax Class for Customer</label>
-                    <source_model>Magento\Tax\Model\Config\Source\TaxClass\Customer</source_model>
+                    <source_model>Magento\Tax\Model\TaxClass\Source\Customer</source_model>
                 </field>
             </group>
             <group id="calculation" translate="label" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
diff --git a/app/code/Magento/Tax/etc/events.xml b/app/code/Magento/Tax/etc/events.xml
index 25f9156c435e75b4eef5d52696c85618be87b010..0efe81f7dcf9d0cca9a7cf652c1bbd8f69bf5a16 100644
--- a/app/code/Magento/Tax/etc/events.xml
+++ b/app/code/Magento/Tax/etc/events.xml
@@ -30,9 +30,6 @@
     <event name="sales_order_save_after">
         <observer name="tax" instance="Magento\Tax\Model\Observer" method="salesEventOrderAfterSave" />
     </event>
-    <event name="catalog_product_collection_load_after">
-        <observer name="tax" instance="Magento\Tax\Model\Observer" method="addTaxPercentToProductCollection" />
-    </event>
     <event name="sales_quote_collect_totals_before">
         <observer name="tax" instance="Magento\Tax\Model\Observer" method="quoteCollectTotalsBefore" />
     </event>
diff --git a/app/code/Magento/Tax/i18n/de_DE.csv b/app/code/Magento/Tax/i18n/de_DE.csv
index e1c992f8e2d82d75d2afa8477ba3e5e93b08ec79..e324e119a78f0eac61bbce517a86289682524583 100644
--- a/app/code/Magento/Tax/i18n/de_DE.csv
+++ b/app/code/Magento/Tax/i18n/de_DE.csv
@@ -14,7 +14,6 @@ Code,Code
 "Sort Order",Sortierreihenfolge
 "Save and Continue Edit","Speichern und Bearbeitung fortsetzen"
 "Are you sure you want to do this?","Sind Sie sicher, dass sie das tun wollen?"
-"This rule no longer exists.","Diese Regel existiert nicht mehr."
 "New Rule","Neue Regel"
 Priority,Priorität
 "Edit Rule","Regel ändern"
@@ -80,13 +79,11 @@ State,Staat
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","Die Steuerregel wurde gespeichert."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","Diese Regel existiert nicht mehr."
+"This rule no longer exists.","Diese Regel existiert nicht mehr."
 "The tax rule has been deleted.","Die Steuerregel wurde gelöscht."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Versandkosten & Steuern"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/en_US.csv b/app/code/Magento/Tax/i18n/en_US.csv
index 5b3e2253c943f99f64941a03283d0986fc8dc0e4..e12e254b924ba835c1caa9f4cb4264bbdf4e6cbd 100644
--- a/app/code/Magento/Tax/i18n/en_US.csv
+++ b/app/code/Magento/Tax/i18n/en_US.csv
@@ -14,7 +14,6 @@ Code,Code
 "Sort Order","Sort Order"
 "Save and Continue Edit","Save and Continue Edit"
 "Are you sure you want to do this?","Are you sure you want to do this?"
-"This rule no longer exists.","This rule no longer exists."
 "New Rule","New Rule"
 Priority,Priority
 "Edit Rule","Edit Rule"
@@ -80,13 +79,11 @@ State,State
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","The tax rule has been saved."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","This rule no longer exists"
+"This rule no longer exists.","This rule no longer exists."
 "The tax rule has been deleted.","The tax rule has been deleted."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Shipping & Handling Tax"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/es_ES.csv b/app/code/Magento/Tax/i18n/es_ES.csv
index 6f854286d52aca79c439822c4382de02b56a8c1b..723c15cf6a26a2bada545ddc8187105fec711871 100644
--- a/app/code/Magento/Tax/i18n/es_ES.csv
+++ b/app/code/Magento/Tax/i18n/es_ES.csv
@@ -14,7 +14,6 @@ Code,Código
 "Sort Order","Ordenar Pedido"
 "Save and Continue Edit","Guardar y continuar editando"
 "Are you sure you want to do this?","¿Estás seguro de querer hacer esto?"
-"This rule no longer exists.","Esta regla ya no existe."
 "New Rule","Nueva Regla"
 Priority,Prioridad
 "Edit Rule","Editar Regla"
@@ -80,13 +79,11 @@ State,Estado
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","Esta regla tributaria ha sido guardada."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","Esta regla ya no existe"
+"This rule no longer exists.","Esta regla ya no existe."
 "The tax rule has been deleted.","Esta regla tributaria ha sido eliminada."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Impuestos de envío y manipulación"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/fr_FR.csv b/app/code/Magento/Tax/i18n/fr_FR.csv
index 010f1d192fd49f9b9db84385cf644fbce062d0e6..f07a4884506f9500cb1c449a14ee1f9d9144e0ba 100644
--- a/app/code/Magento/Tax/i18n/fr_FR.csv
+++ b/app/code/Magento/Tax/i18n/fr_FR.csv
@@ -14,7 +14,6 @@ Code,Code
 "Sort Order","Trier les widgets"
 "Save and Continue Edit","Sauvegarder et continuer l'édition"
 "Are you sure you want to do this?","Êtes-vous sûrs de vouloir faire celà?"
-"This rule no longer exists.","Cette règle n'existe plus."
 "New Rule","Nouvelle règle"
 Priority,Priorité
 "Edit Rule","Éditer la règle"
@@ -80,13 +79,11 @@ State,État
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","La règle de taxe a été enregistrée."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","Cette règle n'existe plus"
+"This rule no longer exists.","Cette règle n'existe plus."
 "The tax rule has been deleted.","La règle de taxe a été supprimée."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Expédition & Frais de traitement"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/nl_NL.csv b/app/code/Magento/Tax/i18n/nl_NL.csv
index 558df8d20fa7a9cad41d614027360c0f9c6a5584..dc5ec7e7ccf1410cba8ae4088cd6086806101616 100644
--- a/app/code/Magento/Tax/i18n/nl_NL.csv
+++ b/app/code/Magento/Tax/i18n/nl_NL.csv
@@ -14,7 +14,6 @@ Code,Code
 "Sort Order","Sorteer Bestelling"
 "Save and Continue Edit","Opslaan en doorgaan met bewerken"
 "Are you sure you want to do this?","Weet je zeker dat je dit wilt doen?"
-"This rule no longer exists.","Deze regel bestaat niet meer"
 "New Rule","Nieuwe Regel"
 Priority,Prioriteit
 "Edit Rule","Pas Regel aan"
@@ -80,13 +79,11 @@ State,Provincie
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","De belastingregel is opgeslagen."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","Deze regel bestaat niet meer"
+"This rule no longer exists.","Deze regel bestaat niet meer."
 "The tax rule has been deleted.","De belastingregel is verwijderd."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Verzending - en verwerkingstax"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/pt_BR.csv b/app/code/Magento/Tax/i18n/pt_BR.csv
index 188e7b29719b9637feeb52fd716d67a0e0474714..f1955d8bfca35ca1b29924503b04fdd84c9db905 100644
--- a/app/code/Magento/Tax/i18n/pt_BR.csv
+++ b/app/code/Magento/Tax/i18n/pt_BR.csv
@@ -14,7 +14,6 @@ Code,Código
 "Sort Order","Classificar pedido"
 "Save and Continue Edit","Salvar e continuar a editar"
 "Are you sure you want to do this?","Tem certeza de que quer fazer isso?"
-"This rule no longer exists.","Essa regra não existe mais."
 "New Rule","Nova Regra"
 Priority,Prioridade
 "Edit Rule","Editar regra"
@@ -80,13 +79,11 @@ State,Estado
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.","A regra fiscal foi salva."
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists","A regra não existe mais."
+"This rule no longer exists.","A regra não existe mais."
 "The tax rule has been deleted.","A regra fiscal foi eliminada."
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax","Taxa de Envio & Manuseio"
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/i18n/zh_CN.csv b/app/code/Magento/Tax/i18n/zh_CN.csv
index f053c0c22be1bf2d6639627c7c17b878a6321117..4952571d102d65ed899e3c7bcd693960ccc3eb36 100644
--- a/app/code/Magento/Tax/i18n/zh_CN.csv
+++ b/app/code/Magento/Tax/i18n/zh_CN.csv
@@ -14,7 +14,6 @@ Code,代码
 "Sort Order",排序顺序
 "Save and Continue Edit",保存并继续编辑
 "Are you sure you want to do this?",您是否确认要这样做?
-"This rule no longer exists.",该规则已不存在。
 "New Rule",新规则
 Priority,优先级
 "Edit Rule",修改规则
@@ -80,13 +79,11 @@ State,å·ž
 "New Tax Rule","New Tax Rule"
 "The tax rule has been saved.",该税务规则已保存。
 "Something went wrong saving this tax rule.","Something went wrong saving this tax rule."
-"This rule no longer exists",该规则不存在。
+"This rule no longer exists.",该规则不存在。
 "The tax rule has been deleted.",该税务规则已被删除。
 "Something went wrong deleting this tax rule.","Something went wrong deleting this tax rule."
 "Something went wrong saving this tax class.","Something went wrong saving this tax class."
 "Something went wrong deleting this tax class.","Something went wrong deleting this tax class."
-"Invalid type of tax class specified.","Invalid type of tax class specified."
-"Invalid name of tax class specified.","Invalid name of tax class specified."
 "Shipping & Handling Tax",处理、运送及税金费用
 "Please fill all required fields with valid information.","Please fill all required fields with valid information."
 "Rate Percent should be a positive number.","Rate Percent should be a positive number."
diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml
index 7e5f4a76f978e6eb53601a2a55e753ce862c16fe..80a0368ed5665c54a0b7c2544f314873e5ff3634 100644
--- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml
+++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rate_block.xml
@@ -28,7 +28,7 @@
         <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.tax.rate.grid" as="grid">
             <arguments>
                 <argument name="id" xsi:type="string">tax_rate_grid</argument>
-                <argument name="dataSource" xsi:type="object">Magento\Tax\Model\Resource\Calculation\Grid\Collection</argument>
+                <argument name="dataSource" xsi:type="object">Magento\Tax\Service\V1\Collection\TaxRateCollection</argument>
                 <argument name="default_sort" xsi:type="string">region_name</argument>
                 <argument name="default_dir" xsi:type="string">ASC</argument>
                 <argument name="save_parameters_in_session" xsi:type="string">1</argument>
diff --git a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml
index 56f0be480113ae2bf17172ab91fc6b79f8db2078..92263d40e7567823236f6666a8dfa38fb17f3672 100644
--- a/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml
+++ b/app/code/Magento/Tax/view/adminhtml/layout/tax_rule_block.xml
@@ -28,7 +28,7 @@
         <block class="Magento\Backend\Block\Widget\Grid" name="adminhtml.block.tax.rule.grid" as="grid">
             <arguments>
                 <argument name="id" xsi:type="string">taxRuleGrid</argument>
-                <argument name="dataSource" xsi:type="object">Magento\Tax\Model\Resource\Rule\Grid\Collection</argument>
+                <argument name="dataSource" xsi:type="object">Magento\Tax\Service\V1\Collection\TaxRuleCollection</argument>
                 <argument name="default_sort" xsi:type="string">tax_rule_id</argument>
                 <argument name="default_dir" xsi:type="string">ASC</argument>
                 <argument name="save_parameters_in_session" xsi:type="string">1</argument>
@@ -38,7 +38,7 @@
                     <argument name="rowUrl" xsi:type="array">
                         <item name="path" xsi:type="string">tax/*/edit</item>
                         <item name="extraParamsTemplate" xsi:type="array">
-                            <item name="rule" xsi:type="string">getId</item>
+                            <item name="rule" xsi:type="string">getTaxCalculationRuleId</item>
                         </item>
                     </argument>
                 </arguments>
@@ -60,7 +60,7 @@
                         <argument name="filter_index" xsi:type="string">ctc.customer_tax_class_id</argument>
                         <argument name="show_missing_option_values" xsi:type="string">1</argument>
                         <argument name="type" xsi:type="string">options</argument>
-                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\Resource\Rule\Grid\Options\CustomerTaxClass"/>
+                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\TaxClass\Source\Customer"/>
                     </arguments>
                 </block>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="product_tax_classes">
@@ -71,7 +71,7 @@
                         <argument name="filter_index" xsi:type="string">ptc.product_tax_class_id</argument>
                         <argument name="show_missing_option_values" xsi:type="string">1</argument>
                         <argument name="type" xsi:type="string">options</argument>
-                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\Resource\Rule\Grid\Options\ProductTaxClass"/>
+                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\TaxClass\Source\Product"/>
                     </arguments>
                 </block>
                 <block class="Magento\Backend\Block\Widget\Grid\Column" as="tax_rates">
@@ -82,7 +82,7 @@
                         <argument name="filter_index" xsi:type="string">rate.tax_calculation_rate_id</argument>
                         <argument name="show_missing_option_values" xsi:type="string">1</argument>
                         <argument name="type" xsi:type="string">options</argument>
-                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\Resource\Rule\Grid\Options\HashOptimized"/>
+                        <argument name="options" xsi:type="options" model="Magento\Tax\Model\Rate\Source"/>
                         <argument name="column_css_class" xsi:type="string">col-title</argument>
                         <argument name="header_css_class" xsi:type="string">col-title</argument>
                     </arguments>
diff --git a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme.php b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme.php
index 3e2b4ccd1834b94dc22de489f09e4e1861823b3b..941c24ecf7574b638e9496fc96e46acf37100c8f 100644
--- a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme.php
+++ b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme.php
@@ -42,7 +42,7 @@ class Theme extends \Magento\Backend\Block\Widget\Grid\Container
             $this->getLayout()->getBlock('page-title')->setPageTitle('Themes');
         }
 
-        $this->_updateButton('add', 'label', __('Add New Theme'));
+        $this->buttonList->update('add', 'label', __('Add New Theme'));
     }
 
     /**
diff --git a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit.php b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit.php
index a385635d699660f2804890e6cfbfa8bc8b7c2a64..2f27ff66564e332577a310b9bbde2fc8909ecf9e 100644
--- a/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit.php
+++ b/app/code/Magento/Theme/Block/Adminhtml/System/Design/Theme/Edit.php
@@ -37,12 +37,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -69,7 +69,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
         $theme = $this->_getCurrentTheme();
         if ($theme) {
             if ($theme->isEditable()) {
-                $this->_addButton(
+                $this->buttonList->add(
                     'save_and_continue',
                     array(
                         'label' => __('Save and Continue Edit'),
@@ -83,8 +83,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                     1
                 );
             } else {
-                $this->_removeButton('save');
-                $this->_removeButton('reset');
+                $this->buttonList->remove('save');
+                $this->buttonList->remove('reset');
             }
 
             if ($theme->isDeletable()) {
@@ -95,10 +95,10 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
                         $message,
                         $this->getUrl('adminhtml/*/delete', array('id' => $theme->getId()))
                     );
-                    $this->_updateButton('delete', 'onclick', $onClick);
+                    $this->buttonList->update('delete', 'onclick', $onClick);
                 }
             } else {
-                $this->_removeButton('delete');
+                $this->buttonList->remove('delete');
             }
         }
 
diff --git a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content.php b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content.php
index a5980bfe89cdf928e1d0bb6b13b60df670fd1327..ee84f22b7aecb669526a67cfe0ae7c50b71d477e 100644
--- a/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content.php
+++ b/app/code/Magento/Theme/Block/Adminhtml/Wysiwyg/Files/Content.php
@@ -41,13 +41,13 @@ class Content extends \Magento\Backend\Block\Widget\Container
     protected $_coreHelper;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Theme\Helper\Storage $storageHelper
      * @param \Magento\Core\Helper\Data $coreHelper
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Theme\Helper\Storage $storageHelper,
         \Magento\Core\Helper\Data $coreHelper,
         array $data = array()
@@ -66,8 +66,9 @@ class Content extends \Magento\Backend\Block\Widget\Container
     {
         parent::_construct();
         $this->_headerText = __('Media Storage');
-        $this->_removeButton('back')->_removeButton('edit');
-        $this->_addButton(
+        $this->buttonList->remove('back');
+        $this->buttonList->remove('edit');
+        $this->buttonList->add(
             'newfolder',
             array(
                 'class' => 'save',
@@ -77,7 +78,7 @@ class Content extends \Magento\Backend\Block\Widget\Container
             )
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'delete_folder',
             array(
                 'class' => 'delete no-display',
@@ -88,7 +89,7 @@ class Content extends \Magento\Backend\Block\Widget\Container
             )
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'delete_files',
             array(
                 'class' => 'delete no-display',
@@ -99,7 +100,7 @@ class Content extends \Magento\Backend\Block\Widget\Container
             )
         );
 
-        $this->_addButton(
+        $this->buttonList->add(
             'insert_files',
             array(
                 'class' => 'save no-display',
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php
index 5bbad678967c34d99d9a7e86b1ba388572bdaed0..522ee68089621452f20789d815e00d9d7e76f4da 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme.php
@@ -27,8 +27,6 @@
  */
 namespace Magento\Theme\Controller\Adminhtml\System\Design;
 
-use Magento\Framework\App\ResponseInterface;
-
 class Theme extends \Magento\Backend\App\Action
 {
     /**
@@ -74,328 +72,6 @@ class Theme extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_eventManager->dispatch('theme_registration_from_filesystem');
-        $this->_view->loadLayout();
-        $this->_setActiveMenu('Magento_Theme::system_design_theme');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Grid ajax action
-     *
-     * @return void
-     */
-    public function gridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Create new theme
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit theme
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $themeId = (int)$this->getRequest()->getParam('id');
-        /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
-        $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
-        try {
-            $theme->setType(\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL);
-            if ($themeId && (!$theme->load($themeId)->getId() || !$theme->isVisible())) {
-                throw new \Magento\Framework\Model\Exception(__('We cannot find theme "%1".', $themeId));
-            }
-            $this->_coreRegistry->register('current_theme', $theme);
-
-            $this->_view->loadLayout();
-            /** @var $tab \Magento\Theme\Block\Adminhtml\System\Design\Theme\Edit\Tab\Css */
-            $tab = $this->_view->getLayout()->getBlock('theme_edit_tabs_tab_css_tab');
-            if ($tab && $tab->canShowTab()) {
-                /** @var $helper \Magento\Core\Helper\Theme */
-                $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
-                $files = $helper->getCssAssets($theme);
-                $tab->setFiles($files);
-            }
-            $this->_setActiveMenu('Magento_Theme::system_design_theme');
-            $this->_view->renderLayout();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('adminhtml/*/');
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We cannot find the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('adminhtml/*/');
-        }
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     */
-    public function saveAction()
-    {
-        $redirectBack = (bool)$this->getRequest()->getParam('back', false);
-        $themeData = $this->getRequest()->getParam('theme');
-        $customCssData = $this->getRequest()->getParam('custom_css_content');
-        $removeJsFiles = (array)$this->getRequest()->getParam('js_removed_files');
-        $reorderJsFiles = array_keys($this->getRequest()->getParam('js_order', array()));
-
-        /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
-        $themeFactory = $this->_objectManager->get('Magento\Framework\View\Design\Theme\FlyweightFactory');
-        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
-        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
-        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
-        $singleFile = $this->_objectManager->create(
-            'Magento\Theme\Model\Theme\SingleFile',
-            array('fileService' => $cssService)
-        );
-        try {
-            if ($this->getRequest()->getPost()) {
-                /** @var $theme \Magento\Core\Model\Theme */
-                if (!empty($themeData['theme_id'])) {
-                    $theme = $themeFactory->create($themeData['theme_id']);
-                } else {
-                    $parentTheme = $themeFactory->create($themeData['parent_id']);
-                    $theme = $parentTheme->getDomainModel(
-                        \Magento\Framework\View\Design\ThemeInterface::TYPE_PHYSICAL
-                    )->createVirtualTheme(
-                        $parentTheme
-                    );
-                }
-                if ($theme && !$theme->isEditable()) {
-                    throw new \Magento\Framework\Model\Exception(__('Theme isn\'t editable.'));
-                }
-                $theme->addData($themeData);
-                if (isset($themeData['preview']['delete'])) {
-                    $theme->getThemeImage()->removePreviewImage();
-                }
-                $theme->getThemeImage()->uploadPreviewImage('preview');
-                $theme->setType(\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL);
-                $theme->save();
-                $customization = $theme->getCustomization();
-                $customization->reorder(
-                    \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE,
-                    $reorderJsFiles
-                );
-                $customization->delete($removeJsFiles);
-                $singleFile->update($theme, $customCssData);
-                $this->messageManager->addSuccess(__('You saved the theme.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_getSession()->setThemeData($themeData);
-            $this->_getSession()->setThemeCustomCssData($customCssData);
-            $redirectBack = true;
-        } catch (\Exception $e) {
-            $this->messageManager->addError('The theme was not saved');
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $redirectBack ? $this->_redirect(
-            'adminhtml/*/edit',
-            array('id' => $theme->getId())
-        ) : $this->_redirect(
-            'adminhtml/*/'
-        );
-    }
-
-    /**
-     * Delete action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $redirectBack = (bool)$this->getRequest()->getParam('back', false);
-        $themeId = $this->getRequest()->getParam('id');
-        try {
-            if ($themeId) {
-                /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
-                $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface')->load($themeId);
-                if (!$theme->getId()) {
-                    throw new \InvalidArgumentException(sprintf('We cannot find a theme with id "%1".', $themeId));
-                }
-                if (!$theme->isVirtual()) {
-                    throw new \InvalidArgumentException(
-                        sprintf('Only virtual theme is possible to delete and theme "%s" isn\'t virtual', $themeId)
-                    );
-                }
-                $theme->delete();
-                $this->messageManager->addSuccess(__('You deleted the theme.'));
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We cannot delete the theme.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        /**
-         * @todo Temporary solution. Theme module should not know about the existence of editor module.
-         */
-        $redirectBack ? $this->_redirect('adminhtml/system_design_editor/index/') : $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * Upload css file
-     *
-     * @return void
-     */
-    public function uploadCssAction()
-    {
-        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
-        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
-        try {
-            $cssFileContent = $serviceModel->uploadCssFile('css_file_uploader');
-            $result = array('error' => false, 'content' => $cssFileContent['content']);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Upload js file
-     *
-     * @return void
-     * @throws \Magento\Framework\Model\Exception
-     */
-    public function uploadJsAction()
-    {
-        $themeId = $this->getRequest()->getParam('id');
-        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
-        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
-        /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
-        $themeFactory = $this->_objectManager->get('Magento\Framework\View\Design\Theme\FlyweightFactory');
-        /** @var $jsService \Magento\Framework\View\Design\Theme\Customization\File\Js */
-        $jsService = $this->_objectManager->get('Magento\Framework\View\Design\Theme\Customization\File\Js');
-        try {
-            $theme = $themeFactory->create($themeId);
-            if (!$theme) {
-                throw new \Magento\Framework\Model\Exception(__('We cannot find a theme with id "%1".', $themeId));
-            }
-            $jsFileData = $serviceModel->uploadJsFile('js_files_uploader');
-            $jsFile = $jsService->create();
-            $jsFile->setTheme($theme);
-            $jsFile->setFileName($jsFileData['filename']);
-            $jsFile->setData('content', $jsFileData['content']);
-            $jsFile->save();
-
-            /** @var $customization \Magento\Framework\View\Design\Theme\Customization */
-            $customization = $this->_objectManager->create(
-                'Magento\Framework\View\Design\Theme\CustomizationInterface',
-                array('theme' => $theme)
-            );
-            $customJsFiles = $customization->getFilesByType(
-                \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE
-            );
-            $result = array('error' => false, 'files' => $customization->generateFileInfo($customJsFiles));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => __('We cannot upload the JS file.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Download custom css file
-     *
-     * @return ResponseInterface|void
-     */
-    public function downloadCustomCssAction()
-    {
-        $themeId = $this->getRequest()->getParam('theme_id');
-        try {
-            /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
-            $themeFactory = $this->_objectManager->create('Magento\Framework\View\Design\Theme\FlyweightFactory');
-            $theme = $themeFactory->create($themeId);
-            if (!$theme) {
-                throw new \InvalidArgumentException(sprintf('We cannot find a theme with id "%1".', $themeId));
-            }
-
-            $customCssFiles = $theme->getCustomization()->getFilesByType(
-                \Magento\Theme\Model\Theme\Customization\File\CustomCss::TYPE
-            );
-            /** @var $customCssFile \Magento\Framework\View\Design\Theme\FileInterface */
-            $customCssFile = reset($customCssFiles);
-            if ($customCssFile && $customCssFile->getContent()) {
-                return $this->_fileFactory->create(
-                    $customCssFile->getFileName(),
-                    array('type' => 'filename', 'value' => $customCssFile->getFullPath()),
-                    \Magento\Framework\App\Filesystem::ROOT_DIR
-                );
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We cannot find file'));
-            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
-    /**
-     * Download css file
-     *
-     * @return ResponseInterface|void
-     */
-    public function downloadCssAction()
-    {
-        $themeId = $this->getRequest()->getParam('theme_id');
-        $file = $this->getRequest()->getParam('file');
-
-        /** @var $helper \Magento\Core\Helper\Theme */
-        $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
-        $fileId = $helper->urlDecode($file);
-        try {
-            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
-            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface')->load($themeId);
-            if (!$theme->getId()) {
-                throw new \InvalidArgumentException(sprintf('Theme not found: "%1".', $themeId));
-            }
-            $asset = $this->_assetRepo->createAsset($fileId, array('themeModel' => $theme));
-            $relPath = $this->_appFileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem::ROOT_DIR)
-                ->getRelativePath($asset->getSourceFile());
-            return $this->_fileFactory->create(
-                $relPath,
-                array(
-                    'type'  => 'filename',
-                    'value' => $relPath
-                ),
-                \Magento\Framework\App\Filesystem::ROOT_DIR
-            );
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('File not found: "%1".', $fileId));
-            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-    }
-
     /**
      * Check the permission to manage themes
      *
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfe1216569d7c0a8e8e3489d509233d4e970e1f3
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Delete.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class Delete extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Delete action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $redirectBack = (bool)$this->getRequest()->getParam('back', false);
+        $themeId = $this->getRequest()->getParam('id');
+        try {
+            if ($themeId) {
+                /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+                $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface')->load($themeId);
+                if (!$theme->getId()) {
+                    throw new \InvalidArgumentException(sprintf('We cannot find a theme with id "%1".', $themeId));
+                }
+                if (!$theme->isVirtual()) {
+                    throw new \InvalidArgumentException(
+                        sprintf('Only virtual theme is possible to delete and theme "%s" isn\'t virtual', $themeId)
+                    );
+                }
+                $theme->delete();
+                $this->messageManager->addSuccess(__('You deleted the theme.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We cannot delete the theme.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        /**
+         * @todo Temporary solution. Theme module should not know about the existence of editor module.
+         */
+        $redirectBack ? $this->_redirect('adminhtml/system_design_editor/index/') : $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d4816d5b449988f201e53fd4507bf1f7eb9b644
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCss.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class DownloadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Download css file
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $themeId = $this->getRequest()->getParam('theme_id');
+        $file = $this->getRequest()->getParam('file');
+
+        /** @var $helper \Magento\Core\Helper\Theme */
+        $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
+        $fileId = $helper->urlDecode($file);
+        try {
+            /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+            $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface')->load($themeId);
+            if (!$theme->getId()) {
+                throw new \InvalidArgumentException(sprintf('Theme not found: "%1".', $themeId));
+            }
+            $asset = $this->_assetRepo->createAsset($fileId, array('themeModel' => $theme));
+            $relPath = $this->_appFileSystem->getDirectoryRead(\Magento\Framework\App\Filesystem::ROOT_DIR)
+                ->getRelativePath($asset->getSourceFile());
+            return $this->_fileFactory->create(
+                $relPath,
+                array(
+                    'type'  => 'filename',
+                    'value' => $relPath
+                ),
+                \Magento\Framework\App\Filesystem::ROOT_DIR
+            );
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('File not found: "%1".', $fileId));
+            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
new file mode 100644
index 0000000000000000000000000000000000000000..9440c09857020752eb3588a88871d8fb669a17b2
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/DownloadCustomCss.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class DownloadCustomCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Download custom css file
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $themeId = $this->getRequest()->getParam('theme_id');
+        try {
+            /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
+            $themeFactory = $this->_objectManager->create('Magento\Framework\View\Design\Theme\FlyweightFactory');
+            $theme = $themeFactory->create($themeId);
+            if (!$theme) {
+                throw new \InvalidArgumentException(sprintf('We cannot find a theme with id "%1".', $themeId));
+            }
+
+            $customCssFiles = $theme->getCustomization()->getFilesByType(
+                \Magento\Theme\Model\Theme\Customization\File\CustomCss::TYPE
+            );
+            /** @var $customCssFile \Magento\Framework\View\Design\Theme\FileInterface */
+            $customCssFile = reset($customCssFiles);
+            if ($customCssFile && $customCssFile->getContent()) {
+                return $this->_fileFactory->create(
+                    $customCssFile->getFileName(),
+                    array('type' => 'filename', 'value' => $customCssFile->getFullPath()),
+                    \Magento\Framework\App\Filesystem::ROOT_DIR
+                );
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We cannot find file'));
+            $this->getResponse()->setRedirect($this->_redirect->getRefererUrl());
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..40e67743d3fb6b45bbe97fb2665ca325f197eaf1
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Edit.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class Edit extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Edit theme
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $themeId = (int)$this->getRequest()->getParam('id');
+        /** @var $theme \Magento\Framework\View\Design\ThemeInterface */
+        $theme = $this->_objectManager->create('Magento\Framework\View\Design\ThemeInterface');
+        try {
+            $theme->setType(\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL);
+            if ($themeId && (!$theme->load($themeId)->getId() || !$theme->isVisible())) {
+                throw new \Magento\Framework\Model\Exception(__('We cannot find theme "%1".', $themeId));
+            }
+            $this->_coreRegistry->register('current_theme', $theme);
+
+            $this->_view->loadLayout();
+            /** @var $tab \Magento\Theme\Block\Adminhtml\System\Design\Theme\Edit\Tab\Css */
+            $tab = $this->_view->getLayout()->getBlock('theme_edit_tabs_tab_css_tab');
+            if ($tab && $tab->canShowTab()) {
+                /** @var $helper \Magento\Core\Helper\Theme */
+                $helper = $this->_objectManager->get('Magento\Core\Helper\Theme');
+                $files = $helper->getCssAssets($theme);
+                $tab->setFiles($files);
+            }
+            $this->_setActiveMenu('Magento_Theme::system_design_theme');
+            $this->_view->renderLayout();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('adminhtml/*/');
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We cannot find the theme.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('adminhtml/*/');
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Grid.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..43a28a15aaed7f7cd97a09a40e75111ade67c3a1
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Grid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class Grid extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Grid ajax action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc68cf274d67b1ca6f666e07de4205b8b060db57
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class Index extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_eventManager->dispatch('theme_registration_from_filesystem');
+        $this->_view->loadLayout();
+        $this->_setActiveMenu('Magento_Theme::system_design_theme');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/NewAction.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..84ca7b11c9810d3bab6b371c9a49639cef4b6329
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class NewAction extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Create new theme
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ee6c482f8bbdf552ebacd159b7fa71065c661e1
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/Save.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class Save extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Save action
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     */
+    public function execute()
+    {
+        $redirectBack = (bool)$this->getRequest()->getParam('back', false);
+        $themeData = $this->getRequest()->getParam('theme');
+        $customCssData = $this->getRequest()->getParam('custom_css_content');
+        $removeJsFiles = (array)$this->getRequest()->getParam('js_removed_files');
+        $reorderJsFiles = array_keys($this->getRequest()->getParam('js_order', array()));
+
+        /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
+        $themeFactory = $this->_objectManager->get('Magento\Framework\View\Design\Theme\FlyweightFactory');
+        /** @var $cssService \Magento\Theme\Model\Theme\Customization\File\CustomCss */
+        $cssService = $this->_objectManager->get('Magento\Theme\Model\Theme\Customization\File\CustomCss');
+        /** @var $singleFile \Magento\Theme\Model\Theme\SingleFile */
+        $singleFile = $this->_objectManager->create(
+            'Magento\Theme\Model\Theme\SingleFile',
+            array('fileService' => $cssService)
+        );
+        try {
+            if ($this->getRequest()->getPost()) {
+                /** @var $theme \Magento\Core\Model\Theme */
+                if (!empty($themeData['theme_id'])) {
+                    $theme = $themeFactory->create($themeData['theme_id']);
+                } else {
+                    $parentTheme = $themeFactory->create($themeData['parent_id']);
+                    $theme = $parentTheme->getDomainModel(
+                        \Magento\Framework\View\Design\ThemeInterface::TYPE_PHYSICAL
+                    )->createVirtualTheme(
+                        $parentTheme
+                    );
+                }
+                if ($theme && !$theme->isEditable()) {
+                    throw new \Magento\Framework\Model\Exception(__('Theme isn\'t editable.'));
+                }
+                $theme->addData($themeData);
+                if (isset($themeData['preview']['delete'])) {
+                    $theme->getThemeImage()->removePreviewImage();
+                }
+                $theme->getThemeImage()->uploadPreviewImage('preview');
+                $theme->setType(\Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL);
+                $theme->save();
+                $customization = $theme->getCustomization();
+                $customization->reorder(
+                    \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE,
+                    $reorderJsFiles
+                );
+                $customization->delete($removeJsFiles);
+                $singleFile->update($theme, $customCssData);
+                $this->messageManager->addSuccess(__('You saved the theme.'));
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_getSession()->setThemeData($themeData);
+            $this->_getSession()->setThemeCustomCssData($customCssData);
+            $redirectBack = true;
+        } catch (\Exception $e) {
+            $this->messageManager->addError('The theme was not saved');
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $redirectBack ? $this->_redirect(
+            'adminhtml/*/edit',
+            array('id' => $theme->getId())
+        ) : $this->_redirect(
+            'adminhtml/*/'
+        );
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
new file mode 100644
index 0000000000000000000000000000000000000000..dff84b6dccd44cefda689ccc39ca4b479a647387
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadCss.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class UploadCss extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Upload css file
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
+        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
+        try {
+            $cssFileContent = $serviceModel->uploadCssFile('css_file_uploader');
+            $result = array('error' => false, 'content' => $cssFileContent['content']);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => __('We cannot upload the CSS file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
new file mode 100644
index 0000000000000000000000000000000000000000..e8211961e1892379fcd805d1671c0944176ea8a7
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Theme/UploadJs.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class UploadJs extends \Magento\Theme\Controller\Adminhtml\System\Design\Theme
+{
+    /**
+     * Upload js file
+     *
+     * @return void
+     * @throws \Magento\Framework\Model\Exception
+     */
+    public function execute()
+    {
+        $themeId = $this->getRequest()->getParam('id');
+        /** @var $serviceModel \Magento\Theme\Model\Uploader\Service */
+        $serviceModel = $this->_objectManager->get('Magento\Theme\Model\Uploader\Service');
+        /** @var $themeFactory \Magento\Framework\View\Design\Theme\FlyweightFactory */
+        $themeFactory = $this->_objectManager->get('Magento\Framework\View\Design\Theme\FlyweightFactory');
+        /** @var $jsService \Magento\Framework\View\Design\Theme\Customization\File\Js */
+        $jsService = $this->_objectManager->get('Magento\Framework\View\Design\Theme\Customization\File\Js');
+        try {
+            $theme = $themeFactory->create($themeId);
+            if (!$theme) {
+                throw new \Magento\Framework\Model\Exception(__('We cannot find a theme with id "%1".', $themeId));
+            }
+            $jsFileData = $serviceModel->uploadJsFile('js_files_uploader');
+            $jsFile = $jsService->create();
+            $jsFile->setTheme($theme);
+            $jsFile->setFileName($jsFileData['filename']);
+            $jsFile->setData('content', $jsFileData['content']);
+            $jsFile->save();
+
+            /** @var $customization \Magento\Framework\View\Design\Theme\Customization */
+            $customization = $this->_objectManager->create(
+                'Magento\Framework\View\Design\Theme\CustomizationInterface',
+                array('theme' => $theme)
+            );
+            $customJsFiles = $customization->getFilesByType(
+                \Magento\Framework\View\Design\Theme\Customization\File\Js::TYPE
+            );
+            $result = array('error' => false, 'files' => $customization->generateFileInfo($customJsFiles));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => __('We cannot upload the JS file.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php
index 11d2d82a2a491b73ce11f0fe52b786eb5e0ed8bb..d36b3805ef74f4c76b2e1b5d2886fc9e2dc5ffc8 100644
--- a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files.php
@@ -27,8 +27,6 @@
  */
 namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg;
 
-use Magento\Framework\App\ResponseInterface;
-
 class Files extends \Magento\Backend\App\Action
 {
     /**
@@ -56,181 +54,6 @@ class Files extends \Magento\Backend\App\Action
         parent::__construct($context);
     }
 
-    /**
-     * Index action
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_view->loadLayout('overlay_popup');
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Tree json action
-     *
-     * @return void
-     */
-    public function treeJsonAction()
-    {
-        try {
-            $this->getResponse()->representJson(
-                $this->_view->getLayout()->createBlock(
-                    'Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Tree'
-                )->getTreeJson(
-                    $this->_getStorage()->getTreeArray()
-                )
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())
-            );
-        }
-    }
-
-    /**
-     * New folder action
-     *
-     * @return void
-     */
-    public function newFolderAction()
-    {
-        $name = $this->getRequest()->getPost('name');
-        try {
-            $path = $this->storage->getCurrentPath();
-            $result = $this->_getStorage()->createFolder($name, $path);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => __('Sorry, there was an unknown error.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Delete folder action
-     *
-     * @return void
-     */
-    public function deleteFolderAction()
-    {
-        try {
-            $path = $this->storage->getCurrentPath();
-            $this->_getStorage()->deleteDirectory($path);
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Contents action
-     *
-     * @return void
-     */
-    public function contentsAction()
-    {
-        try {
-            $this->_view->loadLayout('empty');
-            $this->_view->getLayout()->getBlock('wysiwyg_files.files')->setStorage($this->_getStorage());
-            $this->_view->renderLayout();
-
-            $this->_getSession()->setStoragePath($this->storage->getCurrentPath());
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Files upload action
-     *
-     * @return void
-     */
-    public function uploadAction()
-    {
-        try {
-            $path = $this->storage->getCurrentPath();
-            $result = $this->_getStorage()->uploadFile($path);
-        } catch (\Exception $e) {
-            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
-        }
-        $this->getResponse()->representJson(
-            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-        );
-    }
-
-    /**
-     * Preview image action
-     *
-     * @return ResponseInterface|void
-     */
-    public function previewImageAction()
-    {
-        $file = $this->getRequest()->getParam('file');
-        /** @var $helper \Magento\Theme\Helper\Storage */
-        $helper = $this->_objectManager->get('Magento\Theme\Helper\Storage');
-        try {
-            return $this->_fileFactory->create(
-                $file,
-                array('type' => 'filename', 'value' => $helper->getThumbnailPath($file)),
-                \Magento\Framework\App\Filesystem::MEDIA_DIR
-            );
-        } catch (\Exception $e) {
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('core/index/notfound');
-        }
-    }
-
-    /**
-     * Delete file from media storage
-     *
-     * @return void
-     * @throws \Exception
-     */
-    public function deleteFilesAction()
-    {
-        try {
-            if (!$this->getRequest()->isPost()) {
-                throw new \Exception('Wrong request');
-            }
-            $files = $this->_objectManager->get(
-                'Magento\Core\Helper\Data'
-            )->jsonDecode(
-                $this->getRequest()->getParam('files')
-            );
-            foreach ($files as $file) {
-                $this->_getStorage()->deleteFile($file);
-            }
-        } catch (\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Fire when select image
-     *
-     * @return void
-     */
-    public function onInsertAction()
-    {
-        /** @var $helperStorage \Magento\Theme\Helper\Storage */
-        $helperStorage = $this->_objectManager->get('Magento\Theme\Helper\Storage');
-        $this->getResponse()->setBody($helperStorage->getRelativeUrl());
-    }
-
     /**
      * Get storage
      *
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Contents.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Contents.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e3b9ae074270627badbb98affbbf9d225e3d4ac
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Contents.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class Contents extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Contents action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_view->loadLayout('empty');
+            $this->_view->getLayout()->getBlock('wysiwyg_files.files')->setStorage($this->_getStorage());
+            $this->_view->renderLayout();
+
+            $this->_getSession()->setStoragePath($this->storage->getCurrentPath());
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFiles.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFiles.php
new file mode 100644
index 0000000000000000000000000000000000000000..efb5892592f05ff5c31232abb88b283b2ad52a6d
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFiles.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class DeleteFiles extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Delete file from media storage
+     *
+     * @return void
+     * @throws \Exception
+     */
+    public function execute()
+    {
+        try {
+            if (!$this->getRequest()->isPost()) {
+                throw new \Exception('Wrong request');
+            }
+            $files = $this->_objectManager->get(
+                'Magento\Core\Helper\Data'
+            )->jsonDecode(
+                $this->getRequest()->getParam('files')
+            );
+            foreach ($files as $file) {
+                $this->_getStorage()->deleteFile($file);
+            }
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFolder.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..c69ffcaaaa30a6bd0766ed4676c1556e3b7746d2
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/DeleteFolder.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class DeleteFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Delete folder action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $path = $this->storage->getCurrentPath();
+            $this->_getStorage()->deleteDirectory($path);
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Index.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..e1aa6fb9b91ecfcb07b519b9ba5fbab09f13c7be
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Index.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class Index extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Index action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout('overlay_popup');
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
new file mode 100644
index 0000000000000000000000000000000000000000..deae727d5ae8f84eac169deaa324894d976f25e6
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/NewFolder.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class NewFolder extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * New folder action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $name = $this->getRequest()->getPost('name');
+        try {
+            $path = $this->storage->getCurrentPath();
+            $result = $this->_getStorage()->createFolder($name, $path);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+        } catch (\Exception $e) {
+            $result = array('error' => true, 'message' => __('Sorry, there was an unknown error.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/OnInsert.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/OnInsert.php
new file mode 100644
index 0000000000000000000000000000000000000000..4fb644170d6a3437647972bab1fb929b13c00bf2
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/OnInsert.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class OnInsert extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Fire when select image
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /** @var $helperStorage \Magento\Theme\Helper\Storage */
+        $helperStorage = $this->_objectManager->get('Magento\Theme\Helper\Storage');
+        $this->getResponse()->setBody($helperStorage->getRelativeUrl());
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
new file mode 100644
index 0000000000000000000000000000000000000000..f2ccce01d65ee638f701f084009af34186142555
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/PreviewImage.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+use \Magento\Framework\App\ResponseInterface;
+
+class PreviewImage extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Preview image action
+     *
+     * @return ResponseInterface|void
+     */
+    public function execute()
+    {
+        $file = $this->getRequest()->getParam('file');
+        /** @var $helper \Magento\Theme\Helper\Storage */
+        $helper = $this->_objectManager->get('Magento\Theme\Helper\Storage');
+        try {
+            return $this->_fileFactory->create(
+                $file,
+                array('type' => 'filename', 'value' => $helper->getThumbnailPath($file)),
+                \Magento\Framework\App\Filesystem::MEDIA_DIR
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('core/index/notFound');
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
new file mode 100644
index 0000000000000000000000000000000000000000..e60adadd90afaace287c5cc9ed3c4cfb2a2b9c4b
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/TreeJson.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class TreeJson extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Tree json action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->getResponse()->representJson(
+                $this->_view->getLayout()->createBlock(
+                    'Magento\Theme\Block\Adminhtml\Wysiwyg\Files\Tree'
+                )->getTreeJson(
+                    $this->_getStorage()->getTreeArray()
+                )
+            );
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode(array())
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Upload.php b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Upload.php
new file mode 100644
index 0000000000000000000000000000000000000000..9d91a1db7907b5d690102d9bf56fdf1be3771eba
--- /dev/null
+++ b/app/code/Magento/Theme/Controller/Adminhtml/System/Design/Wysiwyg/Files/Upload.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files;
+
+class Upload extends \Magento\Theme\Controller\Adminhtml\System\Design\Wysiwyg\Files
+{
+    /**
+     * Files upload action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $path = $this->storage->getCurrentPath();
+            $result = $this->_getStorage()->uploadFile($path);
+        } catch (\Exception $e) {
+            $result = array('error' => $e->getMessage(), 'errorcode' => $e->getCode());
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Translation/Controller/Ajax.php b/app/code/Magento/Translation/Controller/Ajax/Index.php
similarity index 93%
rename from app/code/Magento/Translation/Controller/Ajax.php
rename to app/code/Magento/Translation/Controller/Ajax/Index.php
index 70fd664195a915d974af73a3b1a245e61e2d74ff..ab820d8a4976e025bc5e54d870812c6ef30f16c7 100644
--- a/app/code/Magento/Translation/Controller/Ajax.php
+++ b/app/code/Magento/Translation/Controller/Ajax/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Translation\Controller;
+namespace Magento\Translation\Controller\Ajax;
 
-class Ajax extends \Magento\Framework\App\Action\Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Framework\Translate\Inline\ParserInterface
@@ -48,7 +49,7 @@ class Ajax extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $translate = (array)$this->getRequest()->getPost('translate');
 
diff --git a/app/code/Magento/User/Block/User.php b/app/code/Magento/User/Block/User.php
index 48f275397561e4116b49e68ed69dd25d4e21e0cd..d68ea00ffb3c821e1633bd17dc05990cc78affd1 100644
--- a/app/code/Magento/User/Block/User.php
+++ b/app/code/Magento/User/Block/User.php
@@ -36,12 +36,12 @@ class User extends \Magento\Backend\Block\Widget\Grid\Container
     protected $_resourceModel;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\User\Model\Resource\User $resourceModel
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\User\Model\Resource\User $resourceModel,
         array $data = array()
     ) {
diff --git a/app/code/Magento/User/Block/User/Edit.php b/app/code/Magento/User/Block/User/Edit.php
index 7a0aeacb8939ce3cddcaa3c460bdc4d09225bad8..9d8f5b6fde645d6ce03884f484132a609b20e703 100644
--- a/app/code/Magento/User/Block/User/Edit.php
+++ b/app/code/Magento/User/Block/User/Edit.php
@@ -38,12 +38,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -64,8 +64,8 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
 
         parent::_construct();
 
-        $this->_updateButton('save', 'label', __('Save User'));
-        $this->_updateButton('delete', 'label', __('Delete User'));
+        $this->buttonList->update('save', 'label', __('Save User'));
+        $this->buttonList->update('delete', 'label', __('Delete User'));
     }
 
     /**
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth.php b/app/code/Magento/User/Controller/Adminhtml/Auth.php
index 0a19c4f76d6a3984f34557d90a8107a607607511..c92f5632d6bc498f3c805a343ef99e9b2a2d478a 100644
--- a/app/code/Magento/User/Controller/Adminhtml/Auth.php
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth.php
@@ -49,136 +49,6 @@ class Auth extends \Magento\Backend\App\AbstractAction
         $this->_userFactory = $userFactory;
     }
 
-    /**
-     * Forgot administrator password action
-     *
-     * @return void
-     */
-    public function forgotpasswordAction()
-    {
-        $email = (string)$this->getRequest()->getParam('email');
-        $params = $this->getRequest()->getParams();
-
-        if (!empty($email) && !empty($params)) {
-            // Validate received data to be an email address
-            if (\Zend_Validate::is($email, 'EmailAddress')) {
-                $collection = $this->_objectManager->get('Magento\User\Model\Resource\User\Collection');
-                /** @var $collection \Magento\User\Model\Resource\User\Collection */
-                $collection->addFieldToFilter('email', $email);
-                $collection->load(false);
-
-                if ($collection->getSize() > 0) {
-                    foreach ($collection as $item) {
-                        /** @var \Magento\User\Model\User $user */
-                        $user = $this->_userFactory->create()->load($item->getId());
-                        if ($user->getId()) {
-                            $newPassResetToken = $this->_objectManager->get(
-                                'Magento\User\Helper\Data'
-                            )->generateResetPasswordLinkToken();
-                            $user->changeResetPasswordLinkToken($newPassResetToken);
-                            $user->save();
-                            $user->sendPasswordResetConfirmationEmail();
-                        }
-                        break;
-                    }
-                }
-                // @codingStandardsIgnoreStart
-                $this->messageManager->addSuccess(
-                    __(
-                        'If there is an account associated with %1 you will receive an email with a link to reset your password.',
-                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($email)
-                    )
-                );
-                // @codingStandardsIgnoreEnd
-                $this->getResponse()->setRedirect(
-                    $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
-                );
-                return;
-            } else {
-                $this->messageManager->addError(__('Please correct this email address:'));
-            }
-        } elseif (!empty($params)) {
-            $this->messageManager->addError(__('The email address is empty.'));
-        }
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Display reset forgotten password form
-     *
-     * User is redirected on this action when he clicks on the corresponding link in password reset confirmation email
-     *
-     * @return void
-     */
-    public function resetPasswordAction()
-    {
-        $passwordResetToken = (string)$this->getRequest()->getQuery('token');
-        $userId = (int)$this->getRequest()->getQuery('id');
-        try {
-            $this->_validateResetPasswordLinkToken($userId, $passwordResetToken);
-
-            $this->_view->loadLayout();
-
-            $content = $this->_view->getLayout()->getBlock('content');
-            if ($content) {
-                $content->setData('user_id', $userId)->setData('reset_password_link_token', $passwordResetToken);
-            }
-
-            $this->_view->renderLayout();
-        } catch (\Exception $exception) {
-            $this->messageManager->addError(__('Your password reset link has expired.'));
-            $this->_redirect('adminhtml/auth/forgotpassword', array('_nosecret' => true));
-            return;
-        }
-    }
-
-    /**
-     * Reset forgotten password
-     *
-     * Used to handle data received from reset forgotten password form
-     *
-     * @return void
-     */
-    public function resetPasswordPostAction()
-    {
-        $passwordResetToken = (string)$this->getRequest()->getQuery('token');
-        $userId = (int)$this->getRequest()->getQuery('id');
-        $password = (string)$this->getRequest()->getPost('password');
-        $passwordConfirmation = (string)$this->getRequest()->getPost('confirmation');
-
-        try {
-            $this->_validateResetPasswordLinkToken($userId, $passwordResetToken);
-        } catch (\Exception $exception) {
-            $this->messageManager->addError(__('Your password reset link has expired.'));
-            $this->getResponse()->setRedirect(
-                $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
-            );
-            return;
-        }
-
-        /** @var $user \Magento\User\Model\User */
-        $user = $this->_userFactory->create()->load($userId);
-        $user->setPassword($password);
-        $user->setPasswordConfirmation($passwordConfirmation);
-        // Empty current reset password token i.e. invalidate it
-        $user->setRpToken(null);
-        $user->setRpTokenCreatedAt(null);
-        try {
-            $user->save();
-            $this->messageManager->addSuccess(__('Your password has been updated.'));
-            $this->getResponse()->setRedirect(
-                $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
-            );
-        } catch (\Magento\Framework\Model\Exception $exception) {
-            $this->messageManager->addMessages($exception->getMessages());
-            $this->_redirect(
-                'adminhtml/auth/resetpassword',
-                array('_nosecret' => true, '_query' => array('id' => $userId, 'token' => $passwordResetToken))
-            );
-        }
-    }
-
     /**
      * Check if password reset token is valid
      *
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e7b18c2360c0a6114f2978199bc5ff99db5c461
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth/Forgotpassword.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\Auth;
+
+class Forgotpassword extends \Magento\User\Controller\Adminhtml\Auth
+{
+    /**
+     * Forgot administrator password action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $email = (string)$this->getRequest()->getParam('email');
+        $params = $this->getRequest()->getParams();
+
+        if (!empty($email) && !empty($params)) {
+            // Validate received data to be an email address
+            if (\Zend_Validate::is($email, 'EmailAddress')) {
+                $collection = $this->_objectManager->get('Magento\User\Model\Resource\User\Collection');
+                /** @var $collection \Magento\User\Model\Resource\User\Collection */
+                $collection->addFieldToFilter('email', $email);
+                $collection->load(false);
+
+                if ($collection->getSize() > 0) {
+                    foreach ($collection as $item) {
+                        /** @var \Magento\User\Model\User $user */
+                        $user = $this->_userFactory->create()->load($item->getId());
+                        if ($user->getId()) {
+                            $newPassResetToken = $this->_objectManager->get(
+                                'Magento\User\Helper\Data'
+                            )->generateResetPasswordLinkToken();
+                            $user->changeResetPasswordLinkToken($newPassResetToken);
+                            $user->save();
+                            $user->sendPasswordResetConfirmationEmail();
+                        }
+                        break;
+                    }
+                }
+                // @codingStandardsIgnoreStart
+                $this->messageManager->addSuccess(
+                    __(
+                        'If there is an account associated with %1 you will receive an email with a link to reset your password.',
+                        $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($email)
+                    )
+                );
+                // @codingStandardsIgnoreEnd
+                $this->getResponse()->setRedirect(
+                    $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
+                );
+                return;
+            } else {
+                $this->messageManager->addError(__('Please correct this email address:'));
+            }
+        } elseif (!empty($params)) {
+            $this->messageManager->addError(__('The email address is empty.'));
+        }
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPassword.php b/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPassword.php
new file mode 100644
index 0000000000000000000000000000000000000000..19d28ea2a7fd7ca99445219e4fcf634ca8a1346e
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPassword.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\Auth;
+
+class ResetPassword extends \Magento\User\Controller\Adminhtml\Auth
+{
+    /**
+     * Display reset forgotten password form
+     *
+     * User is redirected on this action when he clicks on the corresponding link in password reset confirmation email
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $passwordResetToken = (string)$this->getRequest()->getQuery('token');
+        $userId = (int)$this->getRequest()->getQuery('id');
+        try {
+            $this->_validateResetPasswordLinkToken($userId, $passwordResetToken);
+
+            $this->_view->loadLayout();
+
+            $content = $this->_view->getLayout()->getBlock('content');
+            if ($content) {
+                $content->setData('user_id', $userId)->setData('reset_password_link_token', $passwordResetToken);
+            }
+
+            $this->_view->renderLayout();
+        } catch (\Exception $exception) {
+            $this->messageManager->addError(__('Your password reset link has expired.'));
+            $this->_redirect('adminhtml/auth/forgotpassword', array('_nosecret' => true));
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPasswordPost.php b/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPasswordPost.php
new file mode 100644
index 0000000000000000000000000000000000000000..e055a1669dfd0ba0786d7fd708cc9e8e9e408153
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/Auth/ResetPasswordPost.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\Auth;
+
+class ResetPasswordPost extends \Magento\User\Controller\Adminhtml\Auth
+{
+    /**
+     * Reset forgotten password
+     *
+     * Used to handle data received from reset forgotten password form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $passwordResetToken = (string)$this->getRequest()->getQuery('token');
+        $userId = (int)$this->getRequest()->getQuery('id');
+        $password = (string)$this->getRequest()->getPost('password');
+        $passwordConfirmation = (string)$this->getRequest()->getPost('confirmation');
+
+        try {
+            $this->_validateResetPasswordLinkToken($userId, $passwordResetToken);
+        } catch (\Exception $exception) {
+            $this->messageManager->addError(__('Your password reset link has expired.'));
+            $this->getResponse()->setRedirect(
+                $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
+            );
+            return;
+        }
+
+        /** @var $user \Magento\User\Model\User */
+        $user = $this->_userFactory->create()->load($userId);
+        $user->setPassword($password);
+        $user->setPasswordConfirmation($passwordConfirmation);
+        // Empty current reset password token i.e. invalidate it
+        $user->setRpToken(null);
+        $user->setRpTokenCreatedAt(null);
+        try {
+            $user->save();
+            $this->messageManager->addSuccess(__('Your password has been updated.'));
+            $this->getResponse()->setRedirect(
+                $this->_objectManager->get('Magento\Backend\Helper\Data')->getHomePageUrl()
+            );
+        } catch (\Magento\Framework\Model\Exception $exception) {
+            $this->messageManager->addMessages($exception->getMessages());
+            $this->_redirect(
+                'adminhtml/auth/resetpassword',
+                array('_nosecret' => true, '_query' => array('id' => $userId, 'token' => $passwordResetToken))
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User.php b/app/code/Magento/User/Controller/Adminhtml/User.php
index 38eacb24a784e92f8b47aacb695d93843bf49045..efb3bb321a88ff79144f3be5d2641d2f96896b40 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User.php
@@ -75,151 +75,6 @@ class User extends \Magento\Backend\App\AbstractAction
         return $this;
     }
 
-    /**
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Users'));
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * @return void
-     */
-    public function editAction()
-    {
-        $this->_title->add(__('Users'));
-
-        $userId = $this->getRequest()->getParam('user_id');
-        /** @var \Magento\User\Model\User $model */
-        $model = $this->_userFactory->create();
-
-        if ($userId) {
-            $model->load($userId);
-            if (!$model->getId()) {
-                $this->messageManager->addError(__('This user no longer exists.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            }
-        } else {
-            $model->setInterfaceLocale(\Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
-        }
-
-        $this->_title->add($model->getId() ? $model->getName() : __('New User'));
-
-        // Restore previously entered form data from session
-        $data = $this->_session->getUserData(true);
-        if (!empty($data)) {
-            $model->setData($data);
-        }
-
-        $this->_coreRegistry->register('permissions_user', $model);
-
-        if (isset($userId)) {
-            $breadcrumb = __('Edit User');
-        } else {
-            $breadcrumb = __('New User');
-        }
-        $this->_initAction()->_addBreadcrumb($breadcrumb, $breadcrumb);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * AJAX customer validation action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(0);
-        $errors = null;
-        $userId = (int)$this->getRequest()->getParam('user_id');
-        $data = $this->getRequest()->getPost();
-        try {
-            /** @var $model \Magento\User\Model\User */
-            $model = $this->_userFactory->create()->load($userId);
-            $model->setData($this->_getAdminUserData($data));
-            $errors = $model->validate();
-        } catch (\Magento\Framework\Model\Exception $exception) {
-            /* @var $error Error */
-            foreach ($exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR) as $error) {
-                $errors[] = $error->getText();
-            }
-        }
-
-        if ($errors !== true && !empty($errors)) {
-            foreach ($errors as $error) {
-                $this->messageManager->addError($error);
-            }
-            $response->setError(1);
-            $this->_view->getLayout()->initMessages();
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-
-        $this->getResponse()->representJson($response->toJson());
-    }
-
-    /**
-     * @return void
-     */
-    public function saveAction()
-    {
-        $userId = (int)$this->getRequest()->getParam('user_id');
-        $data = $this->getRequest()->getPost();
-        if (!$data) {
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        /** @var $model \Magento\User\Model\User */
-        $model = $this->_userFactory->create()->load($userId);
-        if ($userId && $model->isObjectNew()) {
-            $this->messageManager->addError(__('This user no longer exists.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        $model->setData($this->_getAdminUserData($data));
-        $uRoles = $this->getRequest()->getParam('roles', array());
-        if (count($uRoles)) {
-            $model->setRoleId($uRoles[0]);
-        }
-
-        $currentUser = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser();
-        if ($userId == $currentUser->getId() && $this->_objectManager->get(
-            'Magento\Framework\Locale\Validator'
-        )->isValid(
-            $data['interface_locale']
-        )
-        ) {
-            $this->_objectManager->get(
-                'Magento\Backend\Model\Locale\Manager'
-            )->switchBackendInterfaceLocale(
-                $data['interface_locale']
-            );
-        }
-
-        try {
-            $model->save();
-            $this->messageManager->addSuccess(__('You saved the user.'));
-            $this->_getSession()->setUserData(false);
-            $this->_redirect('adminhtml/*/');
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addMessages($e->getMessages());
-            $this->_getSession()->setUserData($data);
-            $this->_redirect('adminhtml/*/edit', array('_current' => true));
-        }
-    }
-
     /**
      * Retrieve well-formed admin user data from the form input
      *
@@ -240,63 +95,6 @@ class User extends \Magento\Backend\App\AbstractAction
         return $data;
     }
 
-    /**
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $currentUser = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser();
-
-        if ($userId = $this->getRequest()->getParam('user_id')) {
-            if ($currentUser->getId() == $userId) {
-                $this->messageManager->addError(__('You cannot delete your own account.'));
-                $this->_redirect('adminhtml/*/edit', array('user_id' => $userId));
-                return;
-            }
-            try {
-                /** @var \Magento\User\Model\User $model */
-                $model = $this->_userFactory->create();
-                $model->setId($userId);
-                $model->delete();
-                $this->messageManager->addSuccess(__('You deleted the user.'));
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-                $this->_redirect('adminhtml/*/edit', array('user_id' => $this->getRequest()->getParam('user_id')));
-                return;
-            }
-        }
-        $this->messageManager->addError(__('We can\'t find a user to delete.'));
-        $this->_redirect('adminhtml/*/');
-    }
-
-    /**
-     * @return void
-     */
-    public function rolesGridAction()
-    {
-        $userId = $this->getRequest()->getParam('user_id');
-        /** @var \Magento\User\Model\User $model */
-        $model = $this->_userFactory->create();
-
-        if ($userId) {
-            $model->load($userId);
-        }
-        $this->_coreRegistry->register('permissions_user', $model);
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * @return void
-     */
-    public function roleGridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
     /**
      * @return bool
      */
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Delete.php b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..c06aa51749c0106a2400d8e50a9e94979c5e3bc1
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Delete.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class Delete extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $currentUser = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser();
+
+        if ($userId = $this->getRequest()->getParam('user_id')) {
+            if ($currentUser->getId() == $userId) {
+                $this->messageManager->addError(__('You cannot delete your own account.'));
+                $this->_redirect('adminhtml/*/edit', array('user_id' => $userId));
+                return;
+            }
+            try {
+                /** @var \Magento\User\Model\User $model */
+                $model = $this->_userFactory->create();
+                $model->setId($userId);
+                $model->delete();
+                $this->messageManager->addSuccess(__('You deleted the user.'));
+                $this->_redirect('adminhtml/*/');
+                return;
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+                $this->_redirect('adminhtml/*/edit', array('user_id' => $this->getRequest()->getParam('user_id')));
+                return;
+            }
+        }
+        $this->messageManager->addError(__('We can\'t find a user to delete.'));
+        $this->_redirect('adminhtml/*/');
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Edit.php b/app/code/Magento/User/Controller/Adminhtml/User/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d7df97eb8f340bcab1fb875237d30f960b4080f
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Edit.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class Edit extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Users'));
+
+        $userId = $this->getRequest()->getParam('user_id');
+        /** @var \Magento\User\Model\User $model */
+        $model = $this->_userFactory->create();
+
+        if ($userId) {
+            $model->load($userId);
+            if (!$model->getId()) {
+                $this->messageManager->addError(__('This user no longer exists.'));
+                $this->_redirect('adminhtml/*/');
+                return;
+            }
+        } else {
+            $model->setInterfaceLocale(\Magento\Framework\Locale\ResolverInterface::DEFAULT_LOCALE);
+        }
+
+        $this->_title->add($model->getId() ? $model->getName() : __('New User'));
+
+        // Restore previously entered form data from session
+        $data = $this->_session->getUserData(true);
+        if (!empty($data)) {
+            $model->setData($data);
+        }
+
+        $this->_coreRegistry->register('permissions_user', $model);
+
+        if (isset($userId)) {
+            $breadcrumb = __('Edit User');
+        } else {
+            $breadcrumb = __('New User');
+        }
+        $this->_initAction()->_addBreadcrumb($breadcrumb, $breadcrumb);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Index.php b/app/code/Magento/User/Controller/Adminhtml/User/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..08079bef5b1f6ed11ba2c211c14284d018b0bf4a
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Index.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class Index extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Users'));
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/NewAction.php b/app/code/Magento/User/Controller/Adminhtml/User/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..d817bcbbe6eec12d1f69715a5c56b06219972f6c
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/NewAction.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class NewAction extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role.php b/app/code/Magento/User/Controller/Adminhtml/User/Role.php
index c462050041dfd499ba2a61409c92b360960ea71a..43cace8168340f69e66d4ca8b36a7c2c88c94ed9 100644
--- a/app/code/Magento/User/Controller/Adminhtml/User/Role.php
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role.php
@@ -121,205 +121,6 @@ class Role extends \Magento\Backend\App\AbstractAction
         return $this->_coreRegistry->registry('current_role');
     }
 
-    /**
-     * Show grid with roles existing in systems
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Roles'));
-
-        $this->_initAction();
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Action for ajax request from grid
-     *
-     * @return void
-     */
-    public function roleGridAction()
-    {
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Edit role action
-     *
-     * @return void
-     */
-    public function editRoleAction()
-    {
-        $role = $this->_initRole();
-        $this->_initAction();
-
-        if ($role->getId()) {
-            $breadCrumb = __('Edit Role');
-            $breadCrumbTitle = __('Edit Role');
-        } else {
-            $breadCrumb = __('Add New Role');
-            $breadCrumbTitle = __('Add New Role');
-        }
-
-        $this->_title->add($role->getId() ? $role->getRoleName() : __('New Role'));
-
-        $this->_addBreadcrumb($breadCrumb, $breadCrumbTitle);
-
-        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
-        $this->_view->getLayout()->getBlock(
-            'adminhtml.user.role.buttons'
-        )->setRoleId(
-            $role->getId()
-        )->setRoleInfo(
-            $role
-        );
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Remove role action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $rid = $this->getRequest()->getParam('rid', false);
-        /** @var \Magento\User\Model\User $currentUser */
-        $currentUser = $this->_userFactory->create()->setId($this->_authSession->getUser()->getId());
-
-        if (in_array($rid, $currentUser->getRoles())) {
-            $this->messageManager->addError(__('You cannot delete self-assigned roles.'));
-            $this->_redirect('adminhtml/*/editrole', array('rid' => $rid));
-            return;
-        }
-
-        try {
-            $this->_initRole()->delete();
-            $this->messageManager->addSuccess(__('You deleted the role.'));
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while deleting this role.'));
-        }
-
-        $this->_redirect("*/*/");
-    }
-
-    /**
-     * Role form submit action to save or create new role
-     *
-     * @return void
-     */
-    public function saveRoleAction()
-    {
-        $rid = $this->getRequest()->getParam('role_id', false);
-        $resource = $this->getRequest()->getParam('resource', false);
-        $roleUsers = $this->getRequest()->getParam('in_role_user', null);
-        parse_str($roleUsers, $roleUsers);
-        $roleUsers = array_keys($roleUsers);
-
-        $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old');
-        parse_str($oldRoleUsers, $oldRoleUsers);
-        $oldRoleUsers = array_keys($oldRoleUsers);
-
-        $isAll = $this->getRequest()->getParam('all');
-        if ($isAll) {
-            $resource = array($this->_objectManager->get('Magento\Framework\Acl\RootResource')->getId());
-        }
-
-        $role = $this->_initRole('role_id');
-        if (!$role->getId() && $rid) {
-            $this->messageManager->addError(__('This role no longer exists.'));
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-
-        try {
-            $roleName = $this->getRequest()->getParam('rolename', false);
-
-            $role->setName(
-                $roleName
-            )->setPid(
-                $this->getRequest()->getParam('parent_id', false)
-            )->setRoleType(
-                RoleGroup::ROLE_TYPE
-            );
-            $this->_eventManager->dispatch(
-                'admin_permissions_role_prepare_save',
-                array('object' => $role, 'request' => $this->getRequest())
-            );
-            $role->save();
-
-            $this->_rulesFactory->create()->setRoleId($role->getId())->setResources($resource)->saveRel();
-
-            foreach ($oldRoleUsers as $oUid) {
-                $this->_deleteUserFromRole($oUid, $role->getId());
-            }
-
-            foreach ($roleUsers as $nRuid) {
-                $this->_addUserToRole($nRuid, $role->getId());
-            }
-            $this->messageManager->addSuccess(__('You saved the role.'));
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while saving this role.'));
-        }
-        $this->_redirect('adminhtml/*/');
-        return;
-    }
-
-    /**
-     * Action for ajax request from assigned users grid
-     *
-     * @return void
-     */
-    public function editrolegridAction()
-    {
-        $this->_view->loadLayout();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Remove user from role
-     *
-     * @param int $userId
-     * @param int $roleId
-     * @return bool
-     * @throws \Exception
-     */
-    protected function _deleteUserFromRole($userId, $roleId)
-    {
-        try {
-            $this->_userFactory->create()->setRoleId($roleId)->setUserId($userId)->deleteFromRole();
-        } catch (\Exception $e) {
-            throw $e;
-        }
-        return true;
-    }
-
-    /**
-     * Assign user to role
-     *
-     * @param int $userId
-     * @param int $roleId
-     * @return bool
-     */
-    protected function _addUserToRole($userId, $roleId)
-    {
-        $user = $this->_userFactory->create()->load($userId);
-        $user->setRoleId($roleId);
-
-        if ($user->roleUserExists() === true) {
-            return false;
-        } else {
-            $user->save();
-            return true;
-        }
-    }
-
     /**
      * Acl checking
      *
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/Delete.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..02e934322a4c5919839d9e69e7d345262137dfe3
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/Delete.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+class Delete extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Remove role action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $rid = $this->getRequest()->getParam('rid', false);
+        /** @var \Magento\User\Model\User $currentUser */
+        $currentUser = $this->_userFactory->create()->setId($this->_authSession->getUser()->getId());
+
+        if (in_array($rid, $currentUser->getRoles())) {
+            $this->messageManager->addError(__('You cannot delete self-assigned roles.'));
+            $this->_redirect('adminhtml/*/editrole', array('rid' => $rid));
+            return;
+        }
+
+        try {
+            $this->_initRole()->delete();
+            $this->messageManager->addSuccess(__('You deleted the role.'));
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while deleting this role.'));
+        }
+
+        $this->_redirect("*/*/");
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php
new file mode 100644
index 0000000000000000000000000000000000000000..851cdc706efd96ccffc5ab40c5ea543f8e8089ed
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/EditRole.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+class EditRole extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Edit role action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $role = $this->_initRole();
+        $this->_initAction();
+
+        if ($role->getId()) {
+            $breadCrumb = __('Edit Role');
+            $breadCrumbTitle = __('Edit Role');
+        } else {
+            $breadCrumb = __('Add New Role');
+            $breadCrumbTitle = __('Add New Role');
+        }
+
+        $this->_title->add($role->getId() ? $role->getRoleName() : __('New Role'));
+
+        $this->_addBreadcrumb($breadCrumb, $breadCrumbTitle);
+
+        $this->_view->getLayout()->getBlock('head')->setCanLoadExtJs(true);
+        $this->_view->getLayout()->getBlock(
+            'adminhtml.user.role.buttons'
+        )->setRoleId(
+            $role->getId()
+        )->setRoleInfo(
+            $role
+        );
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/Editrolegrid.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/Editrolegrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a1bb1acba3ca30e353653dbc9749bbde1d4e96c
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/Editrolegrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+class Editrolegrid extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Action for ajax request from assigned users grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb060ac46929e3ba5477ca487fa89d51b907b362
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/Index.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+class Index extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Show grid with roles existing in systems
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Roles'));
+
+        $this->_initAction();
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..2aacfa747d834885f9899b183733f153717331d3
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/RoleGrid.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+class RoleGrid extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Action for ajax request from grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
new file mode 100644
index 0000000000000000000000000000000000000000..ffea14b477ab9400896af2566f2c87bd4b63a5fb
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Role/SaveRole.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User\Role;
+
+use \Magento\User\Model\Acl\Role\Group as RoleGroup;
+
+class SaveRole extends \Magento\User\Controller\Adminhtml\User\Role
+{
+    /**
+     * Assign user to role
+     *
+     * @param int $userId
+     * @param int $roleId
+     * @return bool
+     */
+    protected function _addUserToRole($userId, $roleId)
+    {
+        $user = $this->_userFactory->create()->load($userId);
+        $user->setRoleId($roleId);
+
+        if ($user->roleUserExists() === true) {
+            return false;
+        } else {
+            $user->save();
+            return true;
+        }
+    }
+
+    /**
+     * Remove user from role
+     *
+     * @param int $userId
+     * @param int $roleId
+     * @return bool
+     * @throws \Exception
+     */
+    protected function _deleteUserFromRole($userId, $roleId)
+    {
+        try {
+            $this->_userFactory->create()->setRoleId($roleId)->setUserId($userId)->deleteFromRole();
+        } catch (\Exception $e) {
+            throw $e;
+        }
+        return true;
+    }
+
+    /**
+     * Role form submit action to save or create new role
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $rid = $this->getRequest()->getParam('role_id', false);
+        $resource = $this->getRequest()->getParam('resource', false);
+        $roleUsers = $this->getRequest()->getParam('in_role_user', null);
+        parse_str($roleUsers, $roleUsers);
+        $roleUsers = array_keys($roleUsers);
+
+        $oldRoleUsers = $this->getRequest()->getParam('in_role_user_old');
+        parse_str($oldRoleUsers, $oldRoleUsers);
+        $oldRoleUsers = array_keys($oldRoleUsers);
+
+        $isAll = $this->getRequest()->getParam('all');
+        if ($isAll) {
+            $resource = array($this->_objectManager->get('Magento\Framework\Acl\RootResource')->getId());
+        }
+
+        $role = $this->_initRole('role_id');
+        if (!$role->getId() && $rid) {
+            $this->messageManager->addError(__('This role no longer exists.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+
+        try {
+            $roleName = $this->getRequest()->getParam('rolename', false);
+
+            $role->setName(
+                $roleName
+            )->setPid(
+                $this->getRequest()->getParam('parent_id', false)
+            )->setRoleType(
+                RoleGroup::ROLE_TYPE
+            );
+            $this->_eventManager->dispatch(
+                'admin_permissions_role_prepare_save',
+                array('object' => $role, 'request' => $this->getRequest())
+            );
+            $role->save();
+
+            $this->_rulesFactory->create()->setRoleId($role->getId())->setResources($resource)->saveRel();
+
+            foreach ($oldRoleUsers as $oUid) {
+                $this->_deleteUserFromRole($oUid, $role->getId());
+            }
+
+            foreach ($roleUsers as $nRuid) {
+                $this->_addUserToRole($nRuid, $role->getId());
+            }
+            $this->messageManager->addSuccess(__('You saved the role.'));
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while saving this role.'));
+        }
+        $this->_redirect('adminhtml/*/');
+        return;
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php b/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..303941c1b1a72ca970bc619ff0ed69b9fb591bcb
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/RoleGrid.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class RoleGrid extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout(false);
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/RolesGrid.php b/app/code/Magento/User/Controller/Adminhtml/User/RolesGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..05c92032353ac889ad65643942c8f648067ab943
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/RolesGrid.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class RolesGrid extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $userId = $this->getRequest()->getParam('user_id');
+        /** @var \Magento\User\Model\User $model */
+        $model = $this->_userFactory->create();
+
+        if ($userId) {
+            $model->load($userId);
+        }
+        $this->_coreRegistry->register('permissions_user', $model);
+        $this->_view->loadLayout();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Save.php b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..5103bf66175b9e18e14f56e72fdf401376ab45dc
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Save.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class Save extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * @return void
+     */
+    public function execute()
+    {
+        $userId = (int)$this->getRequest()->getParam('user_id');
+        $data = $this->getRequest()->getPost();
+        if (!$data) {
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        /** @var $model \Magento\User\Model\User */
+        $model = $this->_userFactory->create()->load($userId);
+        if ($userId && $model->isObjectNew()) {
+            $this->messageManager->addError(__('This user no longer exists.'));
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        $model->setData($this->_getAdminUserData($data));
+        $uRoles = $this->getRequest()->getParam('roles', array());
+        if (count($uRoles)) {
+            $model->setRoleId($uRoles[0]);
+        }
+
+        $currentUser = $this->_objectManager->get('Magento\Backend\Model\Auth\Session')->getUser();
+        if ($userId == $currentUser->getId() && $this->_objectManager->get(
+            'Magento\Framework\Locale\Validator'
+        )->isValid(
+            $data['interface_locale']
+        )
+        ) {
+            $this->_objectManager->get(
+                'Magento\Backend\Model\Locale\Manager'
+            )->switchBackendInterfaceLocale(
+                $data['interface_locale']
+            );
+        }
+
+        try {
+            $model->save();
+            $this->messageManager->addSuccess(__('You saved the user.'));
+            $this->_getSession()->setUserData(false);
+            $this->_redirect('adminhtml/*/');
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addMessages($e->getMessages());
+            $this->_getSession()->setUserData($data);
+            $this->_redirect('adminhtml/*/edit', array('_current' => true));
+        }
+    }
+}
diff --git a/app/code/Magento/User/Controller/Adminhtml/User/Validate.php b/app/code/Magento/User/Controller/Adminhtml/User/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..f4de3c7430eb83033243b6935aa11d1ef49fdbc8
--- /dev/null
+++ b/app/code/Magento/User/Controller/Adminhtml/User/Validate.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\User\Controller\Adminhtml\User;
+
+class Validate extends \Magento\User\Controller\Adminhtml\User
+{
+    /**
+     * AJAX customer validation action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(0);
+        $errors = null;
+        $userId = (int)$this->getRequest()->getParam('user_id');
+        $data = $this->getRequest()->getPost();
+        try {
+            /** @var $model \Magento\User\Model\User */
+            $model = $this->_userFactory->create()->load($userId);
+            $model->setData($this->_getAdminUserData($data));
+            $errors = $model->validate();
+        } catch (\Magento\Framework\Model\Exception $exception) {
+            /* @var $error Error */
+            foreach ($exception->getMessages(\Magento\Framework\Message\MessageInterface::TYPE_ERROR) as $error) {
+                $errors[] = $error->getText();
+            }
+        }
+
+        if ($errors !== true && !empty($errors)) {
+            foreach ($errors as $error) {
+                $this->messageManager->addError($error);
+            }
+            $response->setError(1);
+            $this->_view->getLayout()->initMessages();
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+
+        $this->getResponse()->representJson($response->toJson());
+    }
+}
diff --git a/app/code/Magento/User/Model/User.php b/app/code/Magento/User/Model/User.php
index 62b85b5ea077259d026a64af2cc8744016c939e2..af20e023055c4897aba392ccd728c8bef39a529f 100644
--- a/app/code/Magento/User/Model/User.php
+++ b/app/code/Magento/User/Model/User.php
@@ -512,6 +512,7 @@ class User extends \Magento\Framework\Model\AbstractModel implements \Magento\Ba
         )->getTransport();
 
         $transport->sendMessage();
+        return $this;
     }
 
     /**
diff --git a/app/code/Magento/Webapi/Controller/Login/Anonymous.php b/app/code/Magento/Webapi/Controller/Login/Anonymous.php
new file mode 100644
index 0000000000000000000000000000000000000000..2cbfa8ee2355a514e24456b3f0dc55bcbde3cc74
--- /dev/null
+++ b/app/code/Magento/Webapi/Controller/Login/Anonymous.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Webapi\Controller\Login;
+
+use Magento\Authz\Model\UserIdentifier;
+
+class Anonymous extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var \Magento\Framework\Session\Generic
+     */
+    protected $session;
+
+    /**
+     * Initialize Login Service
+     *
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Framework\Session\Generic $session
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Session\Generic $session
+    ) {
+        parent::__construct($context);
+        $this->session = $session;
+    }
+
+    /**
+     * Initiate a session for unregistered users. Send back the session id.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->session->start('frontend');
+        $this->session->setUserId(0);
+        $this->session->setUserType(UserIdentifier::USER_TYPE_GUEST);
+        $this->session->regenerateId(true);
+    }
+}
diff --git a/app/code/Magento/Webapi/Controller/Login.php b/app/code/Magento/Webapi/Controller/Login/Index.php
similarity index 89%
rename from app/code/Magento/Webapi/Controller/Login.php
rename to app/code/Magento/Webapi/Controller/Login/Index.php
index d3ff9792e3372a026d369fb40f5ac0a51775756f..feee0d07d5870a5ae93e9538a21b27dcd1ecbbce 100644
--- a/app/code/Magento/Webapi/Controller/Login.php
+++ b/app/code/Magento/Webapi/Controller/Login/Index.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,8 +22,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-
-namespace Magento\Webapi\Controller;
+namespace Magento\Webapi\Controller\Login;
 
 use Magento\Authz\Model\UserIdentifier;
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
@@ -30,10 +30,7 @@ use Magento\Framework\Exception\AuthenticationException;
 use Magento\Webapi\Exception;
 use Magento\Webapi\Exception as HttpException;
 
-/**
- * Login controller
- */
-class Login extends \Magento\Framework\App\Action\Action
+class Index extends \Magento\Framework\App\Action\Action
 {
     /**
      * @var \Magento\Framework\Session\Generic
@@ -77,7 +74,7 @@ class Login extends \Magento\Framework\App\Action\Action
      *
      * @return void
      */
-    public function indexAction()
+    public function execute()
     {
         $contentTypeHeaderValue = $this->getRequest()->getHeader('Content-Type');
         $contentType = $this->getContentType($contentTypeHeaderValue);
@@ -107,19 +104,6 @@ class Login extends \Magento\Framework\App\Action\Action
         $this->session->regenerateId(true);
     }
 
-    /**
-     * Initiate a session for unregistered users. Send back the session id.
-     *
-     * @return void
-     */
-    public function anonymousAction()
-    {
-        $this->session->start('frontend');
-        $this->session->setUserId(0);
-        $this->session->setUserType(UserIdentifier::USER_TYPE_GUEST);
-        $this->session->regenerateId(true);
-    }
-
     /**
      * Get Content-Type value of request given the $header value.
      *
diff --git a/app/code/Magento/Weee/Block/Sales/Order/Totals.php b/app/code/Magento/Weee/Block/Sales/Order/Totals.php
new file mode 100644
index 0000000000000000000000000000000000000000..2e8a7794dc2084defef6f10341c57134b9d81067
--- /dev/null
+++ b/app/code/Magento/Weee/Block/Sales/Order/Totals.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Weee\Block\Sales\Order;
+
+class Totals extends \Magento\Framework\View\Element\Template
+{
+    /**
+     * @var \Magento\Weee\Helper\Data
+     */
+    protected $_weeeData;
+
+    /**
+     * @param \Magento\Weee\Helper\Data $_weeeData
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Weee\Helper\Data $_weeeData,
+        \Magento\Framework\View\Element\Template\Context $context,
+        array $data = array()
+    ) {
+        $this->_weeeData = $_weeeData;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * Get totals source object
+     *
+     * @return \Magento\Sales\Model\Order
+     */
+    public function getSource()
+    {
+        return $this->getParentBlock()->getSource();
+    }
+
+    /**
+     * Create the weee ("FPT") totals summary
+     *
+     * @return $this
+     */
+    public function initTotals()
+    {
+        /** @var $items \Magento\Sales\Model\Order\Item[] */
+        $items = $this->getSource()->getAllItems();
+        $store = $this->getSource()->getStore();
+
+        $weeeTotal = $this->_weeeData->getTotalAmounts($items, $store);
+        if ($weeeTotal) {
+            // Add our total information to the set of other totals
+            $total = new \Magento\Framework\Object(
+                array(
+                    'code' => $this->getNameInLayout(),
+                    'label' => __('FPT'),
+                    'value' => $weeeTotal
+                )
+            );
+            if ($this->getBeforeCondition()) {
+                $this->getParentBlock()->addTotalBefore($total, $this->getBeforeCondition());
+            } else {
+                $this->getParentBlock()->addTotal($total, $this->getAfterCondition());
+            }
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Weee/Helper/Data.php b/app/code/Magento/Weee/Helper/Data.php
index 2897ec77cecb0944386abee896c9c00b481cc210..da26c0d20dcafa77310f8b3b0d426be8fac29179 100644
--- a/app/code/Magento/Weee/Helper/Data.php
+++ b/app/code/Magento/Weee/Helper/Data.php
@@ -72,7 +72,6 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Weee\Model\Config $weeeConfig
      * @param \Magento\Tax\Helper\Data $taxData
      * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
@@ -182,14 +181,26 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
     /**
      * Check if fixed taxes are used in system
      *
-     * @param Store $store
-     * @return bool
+     * @param   null|string|bool|int|Store $store
+     * @return  bool
      */
     public function isEnabled($store = null)
     {
         return $this->_weeeConfig->isEnabled($store);
     }
 
+    /**
+     * Check if the FPT totals line(s) should be displayed with tax included
+     *
+     * @param   null|string|bool|int|Store $store
+     * @return  bool
+     */
+    public function displayTotalsInclTax($store = null)
+    {
+        // If catalog prices include tax, then display FPT totals with tax included
+        return $this->_taxData->priceIncludesTax($store);
+    }
+
     /**
      * Get weee tax amount for product based on website
      *
@@ -521,4 +532,25 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         }
         return $totalTaxForWeeeTax;
     }
+
+    /**
+     * Returns the total amount of FPT across all items.  Used for displaying the FPT totals line item.
+     *
+     * @param  \Magento\Sales\Model\Quote\Item\AbstractItem[] $items
+     * @param  null|string|bool|int|Store $store
+     * @return float
+     */
+    public function getTotalAmounts($items, $store = null)
+    {
+        $weeeTotal = 0;
+        $displayTotalsInclTax = $this->displayTotalsInclTax($store);
+        foreach ($items as $item) {
+            if ($displayTotalsInclTax) {
+                $weeeTotal += $this->getRowWeeeTaxInclTax($item);
+            } else {
+                $weeeTotal += $item->getWeeeTaxAppliedRowAmount();
+            }
+        }
+        return $weeeTotal;
+    }
 }
diff --git a/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php
new file mode 100644
index 0000000000000000000000000000000000000000..7bdbda04ebd07beae22007d07db0fa225fe7c667
--- /dev/null
+++ b/app/code/Magento/Weee/Model/Sales/Pdf/Weee.php
@@ -0,0 +1,87 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Weee\Model\Sales\Pdf;
+
+class Weee extends \Magento\Sales\Model\Order\Pdf\Total\DefaultTotal
+{
+    /**
+     * @var \Magento\Weee\Helper\Data
+     */
+    protected $_weeeData;
+
+    /**
+     * @param \Magento\Tax\Helper\Data $taxHelper
+     * @param \Magento\Tax\Model\Calculation $taxCalculation
+     * @param \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $ordersFactory
+     * @param \Magento\Weee\Helper\Data $_weeeData
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Tax\Helper\Data $taxHelper,
+        \Magento\Tax\Model\Calculation $taxCalculation,
+        \Magento\Tax\Model\Resource\Sales\Order\Tax\CollectionFactory $ordersFactory,
+        \Magento\Weee\Helper\Data $_weeeData,
+        array $data = array()
+    ) {
+        $this->_weeeData = $_weeeData;
+        parent::__construct($taxHelper, $taxCalculation, $ordersFactory, $data);
+    }
+
+    /**
+     * Check if weee total amount should be included
+     * array(
+     *  $index => array(
+     *      'amount'   => $amount,
+     *      'label'    => $label,
+     *      'font_size'=> $font_size
+     *  )
+     * )
+     * @return array
+     */
+    public function getTotalsForDisplay()
+    {
+        /** @var $items \Magento\Sales\Model\Order\Item[] */
+        $items = $this->getSource()->getAllItems();
+        $store = $this->getSource()->getStore();
+
+        $weeeTotal = $this->_weeeData->getTotalAmounts($items, $store);
+
+        // If we have no Weee, check if we still need to display it
+        if (!$weeeTotal && !filter_var($this->getDisplayZero(), FILTER_VALIDATE_BOOLEAN)) {
+            return array();
+        }
+
+        // Display the Weee total amount
+        $fontSize = $this->getFontSize() ? $this->getFontSize() : 7;
+        $totals = array(
+            array(
+                'amount' => $this->getOrder()->formatPriceTxt($weeeTotal),
+                'label' => __($this->getTitle()) . ':',
+                'font_size' => $fontSize
+            )
+        );
+
+        return $totals;
+    }
+}
diff --git a/app/code/Magento/Weee/Model/Tax.php b/app/code/Magento/Weee/Model/Tax.php
index 49538e541919b49cb53eb10fc128c24bd88691fd..78a5959b02be7027fbab357a64d2306f4dea7b4c 100644
--- a/app/code/Magento/Weee/Model/Tax.php
+++ b/app/code/Magento/Weee/Model/Tax.php
@@ -238,12 +238,16 @@ class Tax extends \Magento\Framework\Model\AbstractModel
 
         if ($shipping) {
             $customerTaxClass = $shipping->getQuote()->getCustomerTaxClassId();
-            $calculator->setCustomerData($shipping->getQuote()->getCustomerData());
         } else {
             $customerTaxClass = null;
         }
 
-        $rateRequest = $calculator->getRateRequest($shipping, $billing, $customerTaxClass, $store);
+        $rateRequest = $calculator->getRateRequest(
+            $shipping,
+            $billing,
+            $customerTaxClass,
+            $store
+        );
         $defaultRateRequest = $calculator->getDefaultRateRequest($store);
 
         $discountPercent = 0;
diff --git a/app/code/Magento/Weee/Model/Total/Creditmemo/Weee.php b/app/code/Magento/Weee/Model/Total/Creditmemo/Weee.php
index dac3daba06b46fbedfde47a74400415101ef1c19..6996d6984758edcd66f2a800f0bfac81d2a38fbe 100644
--- a/app/code/Magento/Weee/Model/Total/Creditmemo/Weee.php
+++ b/app/code/Magento/Weee/Model/Total/Creditmemo/Weee.php
@@ -51,6 +51,8 @@ class Weee extends \Magento\Sales\Model\Order\Creditmemo\Total\AbstractTotal
     }
 
     /**
+     * Collect Weee amounts for the credit memo
+     *
      * @param Creditmemo $creditmemo
      * @return $this
      */
@@ -102,9 +104,6 @@ class Weee extends \Magento\Sales\Model\Order\Creditmemo\Total\AbstractTotal
         if ($this->_weeeData->includeInSubtotal($store)) {
             $creditmemo->setSubtotal($creditmemo->getSubtotal() + $totalTax);
             $creditmemo->setBaseSubtotal($creditmemo->getBaseSubtotal() + $baseTotalTax);
-        } else {
-            $creditmemo->setTaxAmount($creditmemo->getTaxAmount() + $totalTax);
-            $creditmemo->setBaseTaxAmount($creditmemo->getBaseTaxAmount() + $baseTotalTax);
         }
 
         $creditmemo->setSubtotalInclTax($creditmemo->getSubtotalInclTax() + $weeeTaxAmount);
diff --git a/app/code/Magento/Weee/Model/Total/Invoice/Weee.php b/app/code/Magento/Weee/Model/Total/Invoice/Weee.php
index 09e2e73c4df04eb670d89ef1f95e2edb6c51772b..78c963fd91a2861cca26fe4625c2be7b21245193 100644
--- a/app/code/Magento/Weee/Model/Total/Invoice/Weee.php
+++ b/app/code/Magento/Weee/Model/Total/Invoice/Weee.php
@@ -48,10 +48,10 @@ class Weee extends \Magento\Sales\Model\Order\Invoice\Total\AbstractTotal
     }
 
     /**
-     * Weee tax collector
+     * Collect Weee amounts for the invoice
      *
      * @param \Magento\Sales\Model\Order\Invoice $invoice
-     * @return \Magento\Weee\Model\Total\Invoice\Weee
+     * @return $this
      */
     public function collect(\Magento\Sales\Model\Order\Invoice $invoice)
     {
@@ -100,16 +100,9 @@ class Weee extends \Magento\Sales\Model\Order\Invoice\Total\AbstractTotal
             $baseWeeeInclTax += $baseWeeeTaxAmountInclTax;
         }
 
-        /*
-         * Add FPT to totals
-         * Notice that we check restriction on allowed tax, because
-         * a) for last invoice we don't need to collect FPT - it is automatically collected by subtotal/tax collector,
-         * that adds whole remaining (not invoiced) subtotal/tax value, so fpt is automatically included into it
-         * b) FPT tax is included into order subtotal/tax value, so after multiple invoices with partial item quantities
-         * it can happen that other collector will take some FPT value from shared subtotal/tax order value
-         */
-        $order = $invoice->getOrder();
+        // Add FPT to subtotal and grand total
         if ($this->_weeeData->includeInSubtotal($store)) {
+            $order = $invoice->getOrder();
             $allowedSubtotal = $order->getSubtotal() - $order->getSubtotalInvoiced() - $invoice->getSubtotal();
             $allowedBaseSubtotal = $order->getBaseSubtotal() -
                 $order->getBaseSubtotalInvoiced() -
@@ -119,21 +112,22 @@ class Weee extends \Magento\Sales\Model\Order\Invoice\Total\AbstractTotal
 
             $invoice->setSubtotal($invoice->getSubtotal() + $totalTax);
             $invoice->setBaseSubtotal($invoice->getBaseSubtotal() + $baseTotalTax);
-        } else {
-            $allowedTax = $order->getTaxAmount() - $order->getTaxInvoiced() - $invoice->getTaxAmount();
-            $allowedBaseTax = $order->getBaseTaxAmount() - $order->getBaseTaxInvoiced() - $invoice->getBaseTaxAmount();
-            $totalTax = min($allowedTax, $totalTax);
-            $baseTotalTax = min($allowedBaseTax, $baseTotalTax);
-
-            $invoice->setTaxAmount($invoice->getTaxAmount() + $totalTax);
-            $invoice->setBaseTaxAmount($invoice->getBaseTaxAmount() + $baseTotalTax);
         }
 
-        if (!$invoice->isLast()) {
+        $useWeeeInclTax = true;
+        if ($this->_weeeData->isTaxIncluded($store) && $invoice->isLast()) {
+            $useWeeeInclTax = false;
+        }
+        if ($useWeeeInclTax) {
+            // need to add the Weee amounts including all their taxes
             $invoice->setSubtotalInclTax($invoice->getSubtotalInclTax() + $weeeInclTax);
             $invoice->setBaseSubtotalInclTax($invoice->getBaseSubtotalInclTax() + $baseWeeeInclTax);
+        } else {
+            // since the Subtotal Incl Tax line will already have the taxes on Weee, just add the non-taxable amounts
+            $invoice->setSubtotalInclTax($invoice->getSubtotalInclTax() + $totalTax);
+            $invoice->setBaseSubtotalInclTax($invoice->getBaseSubtotalInclTax() + $baseTotalTax);
         }
-        
+
         $invoice->setGrandTotal($invoice->getGrandTotal() + $totalTax);
         $invoice->setBaseGrandTotal($invoice->getBaseGrandTotal() + $baseTotalTax);
 
diff --git a/app/code/Magento/Weee/Model/Total/Quote/Weee.php b/app/code/Magento/Weee/Model/Total/Quote/Weee.php
index f929e492fb53b66133865217607475fd7b8a49dc..5b9e38184a26ffc8036235b3e68aac28083d0da3 100644
--- a/app/code/Magento/Weee/Model/Total/Quote/Weee.php
+++ b/app/code/Magento/Weee/Model/Total/Quote/Weee.php
@@ -38,25 +38,34 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
      */
     protected $_store;
 
+    /**
+     * @var \Magento\Tax\Model\Calculation
+     */
+    protected $_calculator;
     /**
      * @param \Magento\Tax\Helper\Data $taxData
-     * @param \Magento\Tax\Model\Calculation $calculation
      * @param \Magento\Tax\Model\Config $taxConfig
-     * @param \Magento\Weee\Helper\Data $_weeeData
+     * @param \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService
+     * @param \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder
+     * @param \Magento\Tax\Model\Calculation $calculation
+     * @param \Magento\Weee\Helper\Data $weeeData
      */
     public function __construct(
         \Magento\Tax\Helper\Data $taxData,
-        \Magento\Tax\Model\Calculation $calculation,
         \Magento\Tax\Model\Config $taxConfig,
-        \Magento\Weee\Helper\Data $_weeeData
+        \Magento\Tax\Service\V1\TaxCalculationService $taxCalculationService,
+        \Magento\Tax\Service\V1\Data\QuoteDetailsBuilder $quoteDetailsBuilder,
+        \Magento\Tax\Model\Calculation $calculation,
+        \Magento\Weee\Helper\Data $weeeData
     ) {
-        $this->_weeeData = $_weeeData;
-        parent::__construct($taxData, $calculation, $taxConfig);
+        $this->_weeeData = $weeeData;
+        $this->_calculator = $calculation;
+        parent::__construct($taxData, $taxConfig, $taxCalculationService, $quoteDetailsBuilder);
         $this->setCode('weee');
     }
 
     /**
-     * Collect Weee taxes amount and prepare items prices for taxation and discount
+     * Collect Weee amounts for the quote / order
      *
      * @param   \Magento\Sales\Model\Quote\Address $address
      * @return  $this
@@ -328,13 +337,17 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
      */
     protected function _processTotalAmount($address, $rowValueExclTax, $baseRowValueExclTax, $rowValueInclTax, $baseRowValueInclTax)
     {
+        //TODO: use tax service to calculate tax
         if ($this->_weeeData->includeInSubtotal($this->_store)) {
-            $address->addTotalAmount('subtotal', $this->_store->roundPrice($rowValueExclTax));
-            $address->addBaseTotalAmount('subtotal', $this->_store->roundPrice($baseRowValueExclTax));
+            $address->setExtraSubtotalAmount($this->_store->roundPrice($rowValueExclTax));
+            $address->setBaseExtraSubtotalAmount($this->_store->roundPrice($baseRowValueExclTax));
         } else {
-            $address->setExtraTaxAmount($address->getExtraTaxAmount() + $rowValueExclTax);
-            $address->setBaseExtraTaxAmount($address->getBaseExtraTaxAmount() + $baseRowValueExclTax);
+            $address->addTotalAmount('weee', $rowValueExclTax);
+            $address->addBaseTotalAmount('weee', $baseRowValueExclTax);
         }
+        $address->setExtraTaxAmount($rowValueInclTax - $rowValueExclTax);
+        $address->setBaseExtraTaxAmount($baseRowValueInclTax - $baseRowValueExclTax);
+
         $address->setSubtotalInclTax($address->getSubtotalInclTax() + $this->_store->roundPrice($rowValueInclTax));
         $address->setBaseSubtotalInclTax($address->getBaseSubtotalInclTax() + $this->_store->roundPrice($baseRowValueInclTax));
         return $this;
@@ -376,15 +389,28 @@ class Weee extends \Magento\Tax\Model\Sales\Total\Quote\Tax
     }
 
     /**
-     * Fetch FPT data to address object for display in totals block
+     * Fetch the Weee total amount for display in totals block when building the initial quote
      *
      * @param   \Magento\Sales\Model\Quote\Address $address
      * @return  $this
-     * 
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function fetch(\Magento\Sales\Model\Quote\Address $address)
     {
+        /** @var $items \Magento\Sales\Model\Order\Item[] */
+        $items = $this->_getAddressItems($address);
+        $store = $address->getQuote()->getStore();
+
+        $weeeTotal = $this->_weeeData->getTotalAmounts($items, $store);
+        if ($weeeTotal) {
+            $address->addTotal(
+                array(
+                    'code' => $this->getCode(),
+                    'title' => __('FPT'),
+                    'value' => $weeeTotal,
+                    'area' => null
+                )
+            );
+        }
         return $this;
     }
 
diff --git a/app/code/Magento/Weee/etc/config.xml b/app/code/Magento/Weee/etc/config.xml
index f3a93a1da205cfab048c3d144bf688b33d947d21..b8ee23f8e3e5f672f543d7f75349310124dc2990 100644
--- a/app/code/Magento/Weee/etc/config.xml
+++ b/app/code/Magento/Weee/etc/config.xml
@@ -27,16 +27,16 @@
     <default>
         <sales>
             <totals_sort>
-                <weee>50</weee>
+                <weee>35</weee>
             </totals_sort>
         </sales>
         <tax>
             <weee>
                 <enable>0</enable>
-                <display>0</display>
-                <display_list>0</display_list>
-                <display_sales>0</display_sales>
-                <display_email>0</display_email>
+                <display>1</display>
+                <display_list>1</display_list>
+                <display_sales>1</display_sales>
+                <display_email>1</display_email>
                 <discount>0</discount>
                 <apply_vat>0</apply_vat>
                 <include_in_subtotal>0</include_in_subtotal>
diff --git a/app/code/Magento/Weee/etc/pdf.xml b/app/code/Magento/Weee/etc/pdf.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b803524748eb881e36b8d25ef7a066c22581034b
--- /dev/null
+++ b/app/code/Magento/Weee/etc/pdf.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Sales/etc/pdf_file.xsd">
+    <totals>
+        <total name="weee">
+            <title translate="true">FPT</title>
+            <source_field>weee_amount</source_field>
+            <model>Magento\Weee\Model\Sales\Pdf\Weee</model>
+            <font_size>7</font_size>
+            <display_zero>false</display_zero>
+            <sort_order>250</sort_order>
+        </total>
+    </totals>
+</config>
diff --git a/app/code/Magento/Weee/i18n/de_DE.csv b/app/code/Magento/Weee/i18n/de_DE.csv
index 987466b3bf2300361077d5c1037c8f62a2a94e24..7ec820d9eb205f5c9f27ebef7b290e9a4e9d3ca9 100644
--- a/app/code/Magento/Weee/i18n/de_DE.csv
+++ b/app/code/Magento/Weee/i18n/de_DE.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/en_US.csv b/app/code/Magento/Weee/i18n/en_US.csv
index abc96e1cb00656a59e7b547c64b8bdea3a8de130..e0989690885440cf7da81d32be361a8b2814234e 100644
--- a/app/code/Magento/Weee/i18n/en_US.csv
+++ b/app/code/Magento/Weee/i18n/en_US.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/es_ES.csv b/app/code/Magento/Weee/i18n/es_ES.csv
index 2295ba06b477bd1e18116e6c03e65131a3c5dd50..75afe15b65ecdf9ebdd74e2c5623116e493d9a8a 100644
--- a/app/code/Magento/Weee/i18n/es_ES.csv
+++ b/app/code/Magento/Weee/i18n/es_ES.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/fr_FR.csv b/app/code/Magento/Weee/i18n/fr_FR.csv
index bf3732e4b9de3cd51296b02feb69111a9fb055fe..7570f61e26c2639aa9e0a7ed5406f320cf9a2527 100644
--- a/app/code/Magento/Weee/i18n/fr_FR.csv
+++ b/app/code/Magento/Weee/i18n/fr_FR.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/nl_NL.csv b/app/code/Magento/Weee/i18n/nl_NL.csv
index 2787ed4e79df9b85105ba5af4befcd565f9c61e1..b86bb1920067043ab369c9e056293be0601982c1 100644
--- a/app/code/Magento/Weee/i18n/nl_NL.csv
+++ b/app/code/Magento/Weee/i18n/nl_NL.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/pt_BR.csv b/app/code/Magento/Weee/i18n/pt_BR.csv
index b1e49cdafe5b6bfbde5bed232c874840242384f4..7f2a0e7632ad9ef4553e6225c06ba2aa31ab0d32 100644
--- a/app/code/Magento/Weee/i18n/pt_BR.csv
+++ b/app/code/Magento/Weee/i18n/pt_BR.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/i18n/zh_CN.csv b/app/code/Magento/Weee/i18n/zh_CN.csv
index 17e7ffe826fa9400929b0f6e1d6265c6a7608abf..a2c88c879992e63a8e090089d07671e0b3bc6773 100644
--- a/app/code/Magento/Weee/i18n/zh_CN.csv
+++ b/app/code/Magento/Weee/i18n/zh_CN.csv
@@ -19,3 +19,4 @@ Country/State,Country/State
 "Display Prices In Emails","Display Prices In Emails"
 "Apply Tax To FPT","Apply Tax To FPT"
 "Include FPT In Subtotal","Include FPT In Subtotal"
+"FPT","FPT"
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_new.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_new.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_new.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_updateqty.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_updateqty.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_updateqty.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_view.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_creditmemo_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_new.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_new.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_new.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_updateqty.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_updateqty.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_updateqty.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_view.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_invoice_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/adminhtml/layout/sales_order_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_email_order_creditmemo_items.xml b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_creditmemo_items.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_creditmemo_items.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_email_order_invoice_items.xml b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_invoice_items.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_invoice_items.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_email_order_items.xml b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_items.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_email_order_items.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_creditmemo.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_creditmemo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_creditmemo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_invoice.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_invoice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_invoice.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_print.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_print.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_print.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_printcreditmemo.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_printcreditmemo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_printcreditmemo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_printinvoice.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_printinvoice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_printinvoice.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_guest_view.xml b/app/code/Magento/Weee/view/frontend/layout/sales_guest_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_guest_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_creditmemo.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_creditmemo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_creditmemo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_invoice.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_invoice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_invoice.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_print.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_print.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_print.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_printcreditmemo.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_printcreditmemo.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eee24c2800d6da83a776e4d034494e76942fb4d3
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_printcreditmemo.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="creditmemo_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_cm_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_printinvoice.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_printinvoice.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d4a03372a04f45968b0f12d19509b3f70bf43df8
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_printinvoice.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="invoice_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_inv_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Weee/view/frontend/layout/sales_order_view.xml b/app/code/Magento/Weee/view/frontend/layout/sales_order_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ef888abe192e7870f548c982945b1d26cdaa7b9f
--- /dev/null
+++ b/app/code/Magento/Weee/view/frontend/layout/sales_order_view.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../Core/etc/layout_single.xsd">
+    <referenceBlock name="order_totals">
+        <block class="Magento\Weee\Block\Sales\Order\Totals" name="weee_ord_totals">
+            <action method="setBeforeCondition">
+                <argument name="condition" xsi:type="string">tax</argument>
+            </action>
+        </block>
+    </referenceBlock>
+</layout>
diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget.php b/app/code/Magento/Widget/Block/Adminhtml/Widget.php
index 6896d05c8268a0666c5c446f4305f2b5b48b8db7..a4b0612d68b5d393cd70192840a00b19811a9c97 100644
--- a/app/code/Magento/Widget/Block/Adminhtml/Widget.php
+++ b/app/code/Magento/Widget/Block/Adminhtml/Widget.php
@@ -45,11 +45,11 @@ class Widget extends \Magento\Backend\Block\Widget\Form\Container
 
         $this->removeButton('reset');
         $this->removeButton('back');
-        $this->_updateButton('save', 'label', __('Insert Widget'));
-        $this->_updateButton('save', 'class', 'add-widget');
-        $this->_updateButton('save', 'id', 'insert_button');
-        $this->_updateButton('save', 'onclick', 'wWidget.insertWidget()');
-        $this->_updateButton('save', 'region', 'footer');
+        $this->buttonList->update('save', 'label', __('Insert Widget'));
+        $this->buttonList->update('save', 'class', 'add-widget');
+        $this->buttonList->update('save', 'id', 'insert_button');
+        $this->buttonList->update('save', 'onclick', 'wWidget.insertWidget()');
+        $this->buttonList->update('save', 'region', 'footer');
 
         $this->_formScripts[] = 'wWidget = new WysiwygWidget.Widget(' .
             '"widget_options_form", "select_widget_type", "widget_options", "' .
diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance.php b/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance.php
index aad35ff3d6f2b5994f93c1df3853b71416846bf2..447903a25e48606ed14ba2e78bfdc55382968493 100644
--- a/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance.php
+++ b/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance.php
@@ -42,6 +42,6 @@ class Instance extends \Magento\Backend\Block\Widget\Grid\Container
         $this->_controller = 'adminhtml_widget_instance';
         $this->_headerText = __('Manage Widget Instances');
         parent::_construct();
-        $this->_updateButton('add', 'label', __('Add New Widget Instance'));
+        $this->buttonList->update('add', 'label', __('Add New Widget Instance'));
     }
 }
diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit.php b/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit.php
index 1692e1b410ad14099d2d202ddf9b6a9fd74ec153..8f00e79d8e85b06e927740e819c7991b7d77205a 100644
--- a/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit.php
+++ b/app/code/Magento/Widget/Block/Adminhtml/Widget/Instance/Edit.php
@@ -39,12 +39,12 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected $_coreRegistry = null;
 
     /**
-     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Backend\Block\Widget\Context $context
      * @param \Magento\Framework\Registry $registry
      * @param array $data
      */
     public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Backend\Block\Widget\Context $context,
         \Magento\Framework\Registry $registry,
         array $data = array()
     ) {
@@ -84,7 +84,7 @@ class Edit extends \Magento\Backend\Block\Widget\Form\Container
     protected function _preparelayout()
     {
         if ($this->getWidgetInstance()->isCompleteToCreate()) {
-            $this->_addButton(
+            $this->buttonList->add(
                 'save_and_edit_button',
                 array(
                     'label' => __('Save and Continue Edit'),
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget.php
deleted file mode 100644
index a4ff2b83d17626ffe7a828b0b8879f773305102f..0000000000000000000000000000000000000000
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget.php
+++ /dev/null
@@ -1,130 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-/**
- * Widgets management controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Widget\Controller\Adminhtml;
-
-use Magento\Backend\App\Action;
-
-class Widget extends \Magento\Backend\App\Action
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry;
-
-    /**
-     * @var \Magento\Widget\Model\Widget\Config
-     */
-    protected $_widgetConfig;
-
-    /**
-     * @var \Magento\Widget\Model\Widget
-     */
-    protected $_widget;
-
-    /**
-     * @param \Magento\Backend\App\Action\Context $context
-     * @param \Magento\Widget\Model\Widget\Config $widgetConfig
-     * @param \Magento\Widget\Model\Widget $widget
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(
-        \Magento\Backend\App\Action\Context $context,
-        \Magento\Widget\Model\Widget\Config $widgetConfig,
-        \Magento\Widget\Model\Widget $widget,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_widgetConfig = $widgetConfig;
-        $this->_widget = $widget;
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context);
-    }
-
-    /**
-     * Wisywyg widget plugin main page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        // save extra params for widgets insertion form
-        $skipped = $this->getRequest()->getParam('skip_widgets');
-        $skipped = $this->_widgetConfig->decodeWidgetsFromQuery($skipped);
-
-        $this->_coreRegistry->register('skip_widgets', $skipped);
-
-        $this->_view->loadLayout('empty')->renderLayout();
-    }
-
-    /**
-     * Ajax responder for loading plugin options form
-     *
-     * @return void
-     */
-    public function loadOptionsAction()
-    {
-        try {
-            $this->_view->loadLayout('empty');
-            if ($paramsJson = $this->getRequest()->getParam('widget')) {
-                $request = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonDecode($paramsJson);
-                if (is_array($request)) {
-                    $optionsBlock = $this->_view->getLayout()->getBlock('wysiwyg_widget.options');
-                    if (isset($request['widget_type'])) {
-                        $optionsBlock->setWidgetType($request['widget_type']);
-                    }
-                    if (isset($request['values'])) {
-                        $optionsBlock->setWidgetValues($request['values']);
-                    }
-                }
-                $this->_view->renderLayout();
-            }
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $result = array('error' => true, 'message' => $e->getMessage());
-            $this->getResponse()->representJson(
-                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
-            );
-        }
-    }
-
-    /**
-     * Format widget pseudo-code for inserting into wysiwyg editor
-     *
-     * @return void
-     */
-    public function buildWidgetAction()
-    {
-        $type = $this->getRequest()->getPost('widget_type');
-        $params = $this->getRequest()->getPost('parameters', array());
-        $asIs = $this->getRequest()->getPost('as_is');
-        $html = $this->_widget->getWidgetDeclaration($type, $params, $asIs);
-        $this->getResponse()->setBody($html);
-    }
-}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php
new file mode 100644
index 0000000000000000000000000000000000000000..7d9ddcee3d0b3db1171a99f2e1d3f66db7c4f65e
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/BuildWidget.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget;
+
+class BuildWidget extends \Magento\Backend\App\Action
+{
+    /**
+     * @var \Magento\Widget\Model\Widget
+     */
+    protected $_widget;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Widget\Model\Widget $widget
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Widget\Model\Widget $widget
+    ) {
+        $this->_widget = $widget;
+        parent::__construct($context);
+    }
+
+    /**
+     * Format widget pseudo-code for inserting into wysiwyg editor
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $type = $this->getRequest()->getPost('widget_type');
+        $params = $this->getRequest()->getPost('parameters', array());
+        $asIs = $this->getRequest()->getPost('as_is');
+        $html = $this->_widget->getWidgetDeclaration($type, $params, $asIs);
+        $this->getResponse()->setBody($html);
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c830b72d1f146e9885ec004e32de16ff7d8466a
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Index.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget;
+
+class Index extends \Magento\Backend\App\Action
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @var \Magento\Widget\Model\Widget\Config
+     */
+    protected $_widgetConfig;
+
+    /**
+     * @param \Magento\Backend\App\Action\Context $context
+     * @param \Magento\Widget\Model\Widget\Config $widgetConfig
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(
+        \Magento\Backend\App\Action\Context $context,
+        \Magento\Widget\Model\Widget\Config $widgetConfig,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
+        $this->_widgetConfig = $widgetConfig;
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Wisywyg widget plugin main page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        // save extra params for widgets insertion form
+        $skipped = $this->getRequest()->getParam('skip_widgets');
+        $skipped = $this->_widgetConfig->decodeWidgetsFromQuery($skipped);
+
+        $this->_coreRegistry->register('skip_widgets', $skipped);
+
+        $this->_view->loadLayout('empty')->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
index fba0cf6307695f5655257c3b77df8d946fc35978..0283df67a7c03c2f8ba8a34493ef453515a708db 100644
--- a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance.php
@@ -131,48 +131,6 @@ class Instance extends \Magento\Backend\App\Action
         return $widgetInstance;
     }
 
-    /**
-     * Widget Instances Grid
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $this->_title->add(__('Frontend Apps'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * New widget instance action (forward to edit action)
-     *
-     * @return void
-     */
-    public function newAction()
-    {
-        $this->_forward('edit');
-    }
-
-    /**
-     * Edit widget instance action
-     *
-     * @return void
-     */
-    public function editAction()
-    {
-        $widgetInstance = $this->_initWidgetInstance();
-        if (!$widgetInstance) {
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-
-        $this->_title->add($widgetInstance->getId() ? $widgetInstance->getTitle() : __('New Frontend App Instance'));
-
-        $this->_initAction();
-        $this->_view->renderLayout();
-    }
-
     /**
      * Set body to response
      *
@@ -186,215 +144,6 @@ class Instance extends \Magento\Backend\App\Action
         $this->getResponse()->setBody($body);
     }
 
-    /**
-     * Validate action
-     *
-     * @return void
-     */
-    public function validateAction()
-    {
-        $response = new \Magento\Framework\Object();
-        $response->setError(false);
-        $widgetInstance = $this->_initWidgetInstance();
-        $result = $widgetInstance->validate();
-        if ($result !== true && is_string($result)) {
-            $this->messageManager->addError($result);
-            $this->_view->getLayout()->initMessages();
-            $response->setError(true);
-            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
-        }
-        $responseJson = $response->toJson();
-        $this->_translateInline->processResponseBody($responseJson, true);
-        $this->getResponse()->representJson($responseJson);
-    }
-
-    /**
-     * Save action
-     *
-     * @return void
-     */
-    public function saveAction()
-    {
-        $widgetInstance = $this->_initWidgetInstance();
-        if (!$widgetInstance) {
-            $this->_redirect('adminhtml/*/');
-            return;
-        }
-        $widgetInstance->setTitle(
-            $this->getRequest()->getPost('title')
-        )->setStoreIds(
-            $this->getRequest()->getPost('store_ids', array(0))
-        )->setSortOrder(
-            $this->getRequest()->getPost('sort_order', 0)
-        )->setPageGroups(
-            $this->getRequest()->getPost('widget_instance')
-        )->setWidgetParameters(
-            $this->getRequest()->getPost('parameters')
-        );
-        try {
-            $widgetInstance->save();
-            $this->messageManager->addSuccess(__('The widget instance has been saved.'));
-            if ($this->getRequest()->getParam('back', false)) {
-                $this->_redirect(
-                    'adminhtml/*/edit',
-                    array('instance_id' => $widgetInstance->getId(), '_current' => true)
-                );
-            } else {
-                $this->_redirect('adminhtml/*/');
-            }
-            return;
-        } catch (\Exception $exception) {
-            $this->messageManager->addError($exception->getMessage());
-            $this->_logger->logException($exception);
-            $this->_redirect('adminhtml/*/edit', array('_current' => true));
-            return;
-        }
-        $this->_redirect('adminhtml/*/');
-        return;
-    }
-
-    /**
-     * Delete Action
-     *
-     * @return void
-     */
-    public function deleteAction()
-    {
-        $widgetInstance = $this->_initWidgetInstance();
-        if ($widgetInstance) {
-            try {
-                $widgetInstance->delete();
-                $this->messageManager->addSuccess(__('The widget instance has been deleted.'));
-            } catch (\Exception $e) {
-                $this->messageManager->addError($e->getMessage());
-            }
-        }
-        $this->_redirect('adminhtml/*/');
-        return;
-    }
-
-    /**
-     * Categories chooser Action (Ajax request)
-     *
-     * @return void
-     */
-    public function categoriesAction()
-    {
-        $selected = $this->getRequest()->getParam('selected', '');
-        $isAnchorOnly = $this->getRequest()->getParam('is_anchor_only', 0);
-        $chooser = $this->_view->getLayout()->createBlock(
-            'Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser'
-        )->setUseMassaction(
-            true
-        )->setId(
-            $this->mathRandom->getUniqueHash('categories')
-        )->setIsAnchorOnly(
-            $isAnchorOnly
-        )->setSelectedCategories(
-            explode(',', $selected)
-        );
-        $this->setBody($chooser->toHtml());
-    }
-
-    /**
-     * Products chooser Action (Ajax request)
-     *
-     * @return void
-     */
-    public function productsAction()
-    {
-        $selected = $this->getRequest()->getParam('selected', '');
-        $productTypeId = $this->getRequest()->getParam('product_type_id', '');
-        $chooser = $this->_view->getLayout()->createBlock(
-            'Magento\Catalog\Block\Adminhtml\Product\Widget\Chooser'
-        )->setName(
-            $this->mathRandom->getUniqueHash('products_grid_')
-        )->setUseMassaction(
-            true
-        )->setProductTypeId(
-            $productTypeId
-        )->setSelectedProducts(
-            explode(',', $selected)
-        );
-        /* @var $serializer \Magento\Backend\Block\Widget\Grid\Serializer */
-        $serializer = $this->_view->getLayout()->createBlock(
-            'Magento\Backend\Block\Widget\Grid\Serializer',
-            '',
-            array(
-                'data' => array(
-                    'grid_block' => $chooser,
-                    'callback' => 'getSelectedProducts',
-                    'input_element_name' => 'selected_products',
-                    'reload_param_name' => 'selected_products'
-                )
-            )
-        );
-        $this->setBody($chooser->toHtml() . $serializer->toHtml());
-    }
-
-    /**
-     * Blocks Action (Ajax request)
-     *
-     * @return void
-     */
-    public function blocksAction()
-    {
-        $this->_objectManager->get(
-            'Magento\Framework\App\State'
-        )->emulateAreaCode(
-            'frontend',
-            array($this, 'renderPageContainers')
-        );
-    }
-
-    /**
-     * Render page containers
-     *
-     * @return void
-     */
-    public function renderPageContainers()
-    {
-        /* @var $widgetInstance \Magento\Widget\Model\Widget\Instance */
-        $widgetInstance = $this->_initWidgetInstance();
-        $layout = $this->getRequest()->getParam('layout');
-        $selected = $this->getRequest()->getParam('selected', null);
-        $blocksChooser = $this->_view->getLayout()->createBlock(
-            'Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Chooser\Container'
-        )->setValue(
-            $selected
-        )->setArea(
-            $widgetInstance->getArea()
-        )->setTheme(
-            $widgetInstance->getThemeId()
-        )->setLayoutHandle(
-            $layout
-        )->setAllowedContainers(
-            $widgetInstance->getWidgetSupportedContainers()
-        );
-        $this->setBody($blocksChooser->toHtml());
-    }
-
-    /**
-     * Templates Chooser Action (Ajax request)
-     *
-     * @return void
-     */
-    public function templateAction()
-    {
-        /* @var $widgetInstance \Magento\Widget\Model\Widget\Instance */
-        $widgetInstance = $this->_initWidgetInstance();
-        $block = $this->getRequest()->getParam('block');
-        $selected = $this->getRequest()->getParam('selected', null);
-        $templateChooser = $this->_view->getLayout()->createBlock(
-            'Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Chooser\Template'
-        )->setSelected(
-            $selected
-        )->setWidgetTemplates(
-            $widgetInstance->getWidgetSupportedTemplatesByContainer($block)
-        );
-        $this->setBody($templateChooser->toHtml());
-    }
-
     /**
      * Check is allowed access to action
      *
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Blocks.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Blocks.php
new file mode 100644
index 0000000000000000000000000000000000000000..e990332bbe5112a05a6ea77d95266f3e272cbd93
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Blocks.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Blocks extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Render page containers
+     *
+     * @return void
+     */
+    public function renderPageContainers()
+    {
+        /* @var $widgetInstance \Magento\Widget\Model\Widget\Instance */
+        $widgetInstance = $this->_initWidgetInstance();
+        $layout = $this->getRequest()->getParam('layout');
+        $selected = $this->getRequest()->getParam('selected', null);
+        $blocksChooser = $this->_view->getLayout()->createBlock(
+            'Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Chooser\Container'
+        )->setValue(
+            $selected
+        )->setArea(
+            $widgetInstance->getArea()
+        )->setTheme(
+            $widgetInstance->getThemeId()
+        )->setLayoutHandle(
+            $layout
+        )->setAllowedContainers(
+            $widgetInstance->getWidgetSupportedContainers()
+        );
+        $this->setBody($blocksChooser->toHtml());
+    }
+
+    /**
+     * Blocks Action (Ajax request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_objectManager->get(
+            'Magento\Framework\App\State'
+        )->emulateAreaCode(
+            'frontend',
+            array($this, 'renderPageContainers')
+        );
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Categories.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Categories.php
new file mode 100644
index 0000000000000000000000000000000000000000..729727b0e932d546cffb4baa4d181ae1856bf2e7
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Categories.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Categories extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Categories chooser Action (Ajax request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $selected = $this->getRequest()->getParam('selected', '');
+        $isAnchorOnly = $this->getRequest()->getParam('is_anchor_only', 0);
+        $chooser = $this->_view->getLayout()->createBlock(
+            'Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser'
+        )->setUseMassaction(
+            true
+        )->setId(
+            $this->mathRandom->getUniqueHash('categories')
+        )->setIsAnchorOnly(
+            $isAnchorOnly
+        )->setSelectedCategories(
+            explode(',', $selected)
+        );
+        $this->setBody($chooser->toHtml());
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Delete.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Delete.php
new file mode 100644
index 0000000000000000000000000000000000000000..748c401f25c3a48f3d8129c2fd61ed6a5ed77186
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Delete.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Delete extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Delete Action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $widgetInstance = $this->_initWidgetInstance();
+        if ($widgetInstance) {
+            try {
+                $widgetInstance->delete();
+                $this->messageManager->addSuccess(__('The widget instance has been deleted.'));
+            } catch (\Exception $e) {
+                $this->messageManager->addError($e->getMessage());
+            }
+        }
+        $this->_redirect('adminhtml/*/');
+        return;
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Edit.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Edit.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd6b9afac54aa54389026d05ca7d906a399467e6
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Edit.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Edit extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Edit widget instance action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $widgetInstance = $this->_initWidgetInstance();
+        if (!$widgetInstance) {
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+
+        $this->_title->add($widgetInstance->getId() ? $widgetInstance->getTitle() : __('New Frontend App Instance'));
+
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..99385b2657a637d94e68eac1ed80b6783129fd54
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Index.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Index extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Widget Instances Grid
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_title->add(__('Frontend Apps'));
+
+        $this->_initAction();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/NewAction.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/NewAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..b58ee1a2ea01febf0ce1d1de22dc17e18d440387
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/NewAction.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class NewAction extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * New widget instance action (forward to edit action)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_forward('edit');
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Products.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Products.php
new file mode 100644
index 0000000000000000000000000000000000000000..8161fba8c241f7f6ecb04db83816a2e0e8b6fdde
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Products.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Products extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Products chooser Action (Ajax request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $selected = $this->getRequest()->getParam('selected', '');
+        $productTypeId = $this->getRequest()->getParam('product_type_id', '');
+        $chooser = $this->_view->getLayout()->createBlock(
+            'Magento\Catalog\Block\Adminhtml\Product\Widget\Chooser'
+        )->setName(
+            $this->mathRandom->getUniqueHash('products_grid_')
+        )->setUseMassaction(
+            true
+        )->setProductTypeId(
+            $productTypeId
+        )->setSelectedProducts(
+            explode(',', $selected)
+        );
+        /* @var $serializer \Magento\Backend\Block\Widget\Grid\Serializer */
+        $serializer = $this->_view->getLayout()->createBlock(
+            'Magento\Backend\Block\Widget\Grid\Serializer',
+            '',
+            array(
+                'data' => array(
+                    'grid_block' => $chooser,
+                    'callback' => 'getSelectedProducts',
+                    'input_element_name' => 'selected_products',
+                    'reload_param_name' => 'selected_products'
+                )
+            )
+        );
+        $this->setBody($chooser->toHtml() . $serializer->toHtml());
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ebf73d1097694857a5ee1b9bc021ee70d9e6a95
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Save.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Save extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Save action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $widgetInstance = $this->_initWidgetInstance();
+        if (!$widgetInstance) {
+            $this->_redirect('adminhtml/*/');
+            return;
+        }
+        $widgetInstance->setTitle(
+            $this->getRequest()->getPost('title')
+        )->setStoreIds(
+            $this->getRequest()->getPost('store_ids', array(0))
+        )->setSortOrder(
+            $this->getRequest()->getPost('sort_order', 0)
+        )->setPageGroups(
+            $this->getRequest()->getPost('widget_instance')
+        )->setWidgetParameters(
+            $this->getRequest()->getPost('parameters')
+        );
+        try {
+            $widgetInstance->save();
+            $this->messageManager->addSuccess(__('The widget instance has been saved.'));
+            if ($this->getRequest()->getParam('back', false)) {
+                $this->_redirect(
+                    'adminhtml/*/edit',
+                    array('instance_id' => $widgetInstance->getId(), '_current' => true)
+                );
+            } else {
+                $this->_redirect('adminhtml/*/');
+            }
+            return;
+        } catch (\Exception $exception) {
+            $this->messageManager->addError($exception->getMessage());
+            $this->_logger->logException($exception);
+            $this->_redirect('adminhtml/*/edit', array('_current' => true));
+            return;
+        }
+        $this->_redirect('adminhtml/*/');
+        return;
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Template.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Template.php
new file mode 100644
index 0000000000000000000000000000000000000000..bb58ac7f00cc2e0df31ef628a0c0d13c7eb70877
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Template.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Template extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Templates Chooser Action (Ajax request)
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        /* @var $widgetInstance \Magento\Widget\Model\Widget\Instance */
+        $widgetInstance = $this->_initWidgetInstance();
+        $block = $this->getRequest()->getParam('block');
+        $selected = $this->getRequest()->getParam('selected', null);
+        $templateChooser = $this->_view->getLayout()->createBlock(
+            'Magento\Widget\Block\Adminhtml\Widget\Instance\Edit\Chooser\Template'
+        )->setSelected(
+            $selected
+        )->setWidgetTemplates(
+            $widgetInstance->getWidgetSupportedTemplatesByContainer($block)
+        );
+        $this->setBody($templateChooser->toHtml());
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Validate.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Validate.php
new file mode 100644
index 0000000000000000000000000000000000000000..8089c0e19489f4e92dca72549f909d6f57536e47
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/Instance/Validate.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget\Instance;
+
+class Validate extends \Magento\Widget\Controller\Adminhtml\Widget\Instance
+{
+    /**
+     * Validate action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $response = new \Magento\Framework\Object();
+        $response->setError(false);
+        $widgetInstance = $this->_initWidgetInstance();
+        $result = $widgetInstance->validate();
+        if ($result !== true && is_string($result)) {
+            $this->messageManager->addError($result);
+            $this->_view->getLayout()->initMessages();
+            $response->setError(true);
+            $response->setHtmlMessage($this->_view->getLayout()->getMessagesBlock()->getGroupedHtml());
+        }
+        $response = $response->toJson();
+        $this->_translateInline->processResponseBody($response);
+        $this->_response->representJson($response);
+    }
+}
diff --git a/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php b/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..cbe5c051962c59c031a20f33dd9fd56f31333785
--- /dev/null
+++ b/app/code/Magento/Widget/Controller/Adminhtml/Widget/LoadOptions.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Widget\Controller\Adminhtml\Widget;
+
+class LoadOptions extends \Magento\Backend\App\Action
+{
+    /**
+     * Ajax responder for loading plugin options form
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        try {
+            $this->_view->loadLayout('empty');
+            if ($paramsJson = $this->getRequest()->getParam('widget')) {
+                $request = $this->_objectManager->get('Magento\Core\Helper\Data')->jsonDecode($paramsJson);
+                if (is_array($request)) {
+                    $optionsBlock = $this->_view->getLayout()->getBlock('wysiwyg_widget.options');
+                    if (isset($request['widget_type'])) {
+                        $optionsBlock->setWidgetType($request['widget_type']);
+                    }
+                    if (isset($request['values'])) {
+                        $optionsBlock->setWidgetValues($request['values']);
+                    }
+                }
+                $this->_view->renderLayout();
+            }
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $result = array('error' => true, 'message' => $e->getMessage());
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Core\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index.php b/app/code/Magento/Wishlist/Controller/Index.php
deleted file mode 100644
index 63364d50b7a480bb7372ad10375448dd4a439489..0000000000000000000000000000000000000000
--- a/app/code/Magento/Wishlist/Controller/Index.php
+++ /dev/null
@@ -1,920 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-
-/**
- * Wishlist front controller
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Wishlist\Controller;
-
-use Magento\Framework\App\Action\NotFoundException;
-use Magento\Framework\App\RequestInterface;
-use Magento\Framework\App\ResponseInterface;
-
-class Index extends \Magento\Wishlist\Controller\AbstractController implements
-    \Magento\Catalog\Controller\Product\View\ViewInterface
-{
-    /**
-     * @var \Magento\Framework\App\Response\Http\FileFactory
-     */
-    protected $_fileResponseFactory;
-
-    /**
-     * @var \Magento\Wishlist\Model\Config
-     */
-    protected $_wishlistConfig;
-
-    /**
-     * If true, authentication in this controller (wishlist) could be skipped
-     *
-     * @var bool
-     */
-    protected $_skipAuthentication = false;
-
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry;
-
-    /**
-     * @var \Magento\Framework\Mail\Template\TransportBuilder
-     */
-    protected $_transportBuilder;
-
-    /**
-     * @var \Magento\Framework\Translate\Inline\StateInterface
-     */
-    protected $inlineTranslation;
-
-    /**
-     * @var \Magento\Customer\Helper\View
-     */
-    protected $_customerHelperView;
-
-    /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Framework\Registry $coreRegistry
-     * @param \Magento\Wishlist\Model\Config $wishlistConfig
-     * @param \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory
-     * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
-     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
-     * @param \Magento\Customer\Helper\View $customerHelperView
-     */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Framework\Registry $coreRegistry,
-        \Magento\Wishlist\Model\Config $wishlistConfig,
-        \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory,
-        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
-        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
-        \Magento\Customer\Helper\View $customerHelperView
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        $this->_wishlistConfig = $wishlistConfig;
-        $this->_fileResponseFactory = $fileResponseFactory;
-        $this->_transportBuilder = $transportBuilder;
-        $this->inlineTranslation = $inlineTranslation;
-        $this->_customerHelperView = $customerHelperView;
-        parent::__construct($context, $formKeyValidator, $customerSession);
-    }
-
-    /**
-     * @param RequestInterface $request
-     * @return ResponseInterface
-     * @throws \Magento\Framework\App\Action\NotFoundException
-     */
-    public function dispatch(RequestInterface $request)
-    {
-        if (!$this->_skipAuthentication && !$this->_objectManager->get(
-            'Magento\Customer\Model\Session'
-        )->authenticate(
-            $this
-        )
-        ) {
-            $this->_actionFlag->set('', 'no-dispatch', true);
-            $customerSession = $this->_customerSession;
-            if (!$customerSession->getBeforeWishlistUrl()) {
-                $customerSession->setBeforeWishlistUrl($this->_redirect->getRefererUrl());
-            }
-            $customerSession->setBeforeWishlistRequest($request->getParams());
-        }
-        if (!$this->_objectManager->get(
-            'Magento\Framework\App\Config\ScopeConfigInterface'
-        )->isSetFlag(
-            'wishlist/general/active'
-        )
-        ) {
-            throw new NotFoundException();
-        }
-        return parent::dispatch($request);
-    }
-
-    /**
-     * Set skipping authentication in actions of this controller (wishlist)
-     *
-     * @return $this
-     */
-    public function skipAuthentication()
-    {
-        $this->_skipAuthentication = true;
-        return $this;
-    }
-
-    /**
-     * Retrieve wishlist object
-     *
-     * @param int $wishlistId
-     * @return \Magento\Wishlist\Model\Wishlist|false
-     */
-    protected function _getWishlist($wishlistId = null)
-    {
-        $wishlist = $this->_coreRegistry->registry('wishlist');
-        if ($wishlist) {
-            return $wishlist;
-        }
-
-        try {
-            if (!$wishlistId) {
-                $wishlistId = $this->getRequest()->getParam('wishlist_id');
-            }
-            $customerId = $this->_customerSession->getCustomerId();
-            /* @var \Magento\Wishlist\Model\Wishlist $wishlist */
-            $wishlist = $this->_objectManager->create('Magento\Wishlist\Model\Wishlist');
-            if ($wishlistId) {
-                $wishlist->load($wishlistId);
-            } else {
-                $wishlist->loadByCustomerId($customerId, true);
-            }
-
-            if (!$wishlist->getId() || $wishlist->getCustomerId() != $customerId) {
-                $wishlist = null;
-                throw new \Magento\Framework\Model\Exception(__("The requested wish list doesn't exist."));
-            }
-
-            $this->_coreRegistry->register('wishlist', $wishlist);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            return false;
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Wish List could not be created.'));
-            return false;
-        }
-
-        return $wishlist;
-    }
-
-    /**
-     * Display customer wishlist
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function indexAction()
-    {
-        if (!$this->_getWishlist()) {
-            throw new NotFoundException();
-        }
-        $this->_view->loadLayout();
-
-        $session = $this->_customerSession;
-        $block = $this->_view->getLayout()->getBlock('customer.wishlist');
-        $referer = $session->getAddActionReferer(true);
-        if ($block) {
-            $block->setRefererUrl($this->_redirect->getRefererUrl());
-            if ($referer) {
-                $block->setRefererUrl($referer);
-            }
-        }
-
-        $this->_view->getLayout()->initMessages();
-
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Adding new item
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function addAction()
-    {
-        $wishlist = $this->_getWishlist();
-        if (!$wishlist) {
-            throw new NotFoundException();
-        }
-
-        $session = $this->_customerSession;
-
-        $requestParams = $this->getRequest()->getParams();
-
-        if ($session->getBeforeWishlistRequest()) {
-            $requestParams = $session->getBeforeWishlistRequest();
-            $session->unsBeforeWishlistRequest();
-        }
-
-        $productId = isset($requestParams['product']) ? (int)$requestParams['product'] : null;
-
-        if (!$productId) {
-            $this->_redirect('*/');
-            return;
-        }
-
-        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
-        if (!$product->getId() || !$product->isVisibleInCatalog()) {
-            $this->messageManager->addError(__('We can\'t specify a product.'));
-            $this->_redirect('*/');
-            return;
-        }
-
-        try {
-            $buyRequest = new \Magento\Framework\Object($requestParams);
-
-            $result = $wishlist->addNewItem($product, $buyRequest);
-            if (is_string($result)) {
-                throw new \Magento\Framework\Model\Exception($result);
-            }
-            $wishlist->save();
-
-            $this->_eventManager->dispatch(
-                'wishlist_add_product',
-                array('wishlist' => $wishlist, 'product' => $product, 'item' => $result)
-            );
-
-            $referer = $session->getBeforeWishlistUrl();
-            if ($referer) {
-                $session->setBeforeWishlistUrl(null);
-            } else {
-                $referer = $this->_redirect->getRefererUrl();
-            }
-
-            /**
-             *  Set referer to avoid referring to the compare popup window
-             */
-            $session->setAddActionReferer($referer);
-
-            /** @var $helper \Magento\Wishlist\Helper\Data */
-            $helper = $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-            $message = __(
-                '%1 has been added to your wishlist. Click <a href="%2">here</a> to continue shopping.',
-                $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName()),
-                $this->_objectManager->get('Magento\Framework\Escaper')->escapeUrl($referer)
-            );
-            $this->messageManager->addSuccess($message);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError(
-                __('An error occurred while adding item to wish list: %1', $e->getMessage())
-            );
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while adding item to wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-
-        $this->_redirect('*', array('wishlist_id' => $wishlist->getId()));
-    }
-
-    /**
-     * Action to reconfigure wishlist item
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function configureAction()
-    {
-        $id = (int)$this->getRequest()->getParam('id');
-        try {
-            /* @var $item \Magento\Wishlist\Model\Item */
-            $item = $this->_objectManager->create('Magento\Wishlist\Model\Item');
-            $item->loadWithOptions($id);
-            if (!$item->getId()) {
-                throw new \Magento\Framework\Model\Exception(__('We can\'t load the wish list item.'));
-            }
-            $wishlist = $this->_getWishlist($item->getWishlistId());
-            if (!$wishlist) {
-                throw new NotFoundException();
-            }
-
-            $this->_coreRegistry->register('wishlist_item', $item);
-
-            $params = new \Magento\Framework\Object();
-            $params->setCategoryId(false);
-            $params->setConfigureMode(true);
-            $buyRequest = $item->getBuyRequest();
-            if (!$buyRequest->getQty() && $item->getQty()) {
-                $buyRequest->setQty($item->getQty());
-            }
-            if ($buyRequest->getQty() && !$item->getQty()) {
-                $item->setQty($buyRequest->getQty());
-                $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-            }
-            $params->setBuyRequest($buyRequest);
-            $this->_objectManager->get(
-                'Magento\Catalog\Helper\Product\View'
-            )->prepareAndRender(
-                $item->getProductId(),
-                $this,
-                $params
-            );
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-            $this->_redirect('*');
-            return;
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('We can\'t configure the product.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-            $this->_redirect('*');
-            return;
-        }
-    }
-
-    /**
-     * Action to accept new configuration for a wishlist item
-     *
-     * @return void
-     */
-    public function updateItemOptionsAction()
-    {
-        $session = $this->_customerSession;
-        $productId = (int)$this->getRequest()->getParam('product');
-        if (!$productId) {
-            $this->_redirect('*/');
-            return;
-        }
-
-        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
-        if (!$product->getId() || !$product->isVisibleInCatalog()) {
-            $this->messageManager->addError(__('We can\'t specify a product.'));
-            $this->_redirect('*/');
-            return;
-        }
-
-        try {
-            $id = (int)$this->getRequest()->getParam('id');
-            /* @var \Magento\Wishlist\Model\Item */
-            $item = $this->_objectManager->create('Magento\Wishlist\Model\Item');
-            $item->load($id);
-            $wishlist = $this->_getWishlist($item->getWishlistId());
-            if (!$wishlist) {
-                $this->_redirect('*/');
-                return;
-            }
-
-            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
-
-            $wishlist->updateItem($id, $buyRequest)->save();
-
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-            $this->_eventManager->dispatch(
-                'wishlist_update_item',
-                array('wishlist' => $wishlist, 'product' => $product, 'item' => $wishlist->getItem($id))
-            );
-
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-            $message = __('%1 has been updated in your wish list.', $product->getName());
-            $this->messageManager->addSuccess($message);
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while updating wish list.'));
-            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-        }
-        $this->_redirect('*/*', array('wishlist_id' => $wishlist->getId()));
-    }
-
-    /**
-     * Update wishlist item comments
-     *
-     * @return ResponseInterface|void
-     * @throws NotFoundException
-     */
-    public function updateAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('*/*/');
-        }
-        $wishlist = $this->_getWishlist();
-        if (!$wishlist) {
-            throw new NotFoundException();
-        }
-
-        $post = $this->getRequest()->getPost();
-        if ($post && isset($post['description']) && is_array($post['description'])) {
-            $updatedItems = 0;
-
-            foreach ($post['description'] as $itemId => $description) {
-                $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
-                if ($item->getWishlistId() != $wishlist->getId()) {
-                    continue;
-                }
-
-                // Extract new values
-                $description = (string)$description;
-
-                if ($description == $this->_objectManager->get('Magento\Wishlist\Helper\Data')->defaultCommentString()
-                ) {
-                    $description = '';
-                } elseif (!strlen($description)) {
-                    $description = $item->getDescription();
-                }
-
-                $qty = null;
-                if (isset($post['qty'][$itemId])) {
-                    $qty = $this->_processLocalizedQty($post['qty'][$itemId]);
-                }
-                if (is_null($qty)) {
-                    $qty = $item->getQty();
-                    if (!$qty) {
-                        $qty = 1;
-                    }
-                } elseif (0 == $qty) {
-                    try {
-                        $item->delete();
-                    } catch (\Exception $e) {
-                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
-                        $this->messageManager->addError(__('Can\'t delete item from wishlist'));
-                    }
-                }
-
-                // Check that we need to save
-                if ($item->getDescription() == $description && $item->getQty() == $qty) {
-                    continue;
-                }
-                try {
-                    $item->setDescription($description)->setQty($qty)->save();
-                    $updatedItems++;
-                } catch (\Exception $e) {
-                    $this->messageManager->addError(
-                        __(
-                            'Can\'t save description %1',
-                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($description)
-                        )
-                    );
-                }
-            }
-
-            // save wishlist model for setting date of last update
-            if ($updatedItems) {
-                try {
-                    $wishlist->save();
-                    $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-                } catch (\Exception $e) {
-                    $this->messageManager->addError(__('Can\'t update wish list'));
-                }
-            }
-
-            if (isset($post['save_and_share'])) {
-                $this->_redirect('*/*/share', array('wishlist_id' => $wishlist->getId()));
-                return;
-            }
-        }
-        $this->_redirect('*', array('wishlist_id' => $wishlist->getId()));
-    }
-
-    /**
-     * Remove item
-     *
-     * @return void
-     * @throws NotFoundException
-     */
-    public function removeAction()
-    {
-        $id = (int)$this->getRequest()->getParam('item');
-        $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($id);
-        if (!$item->getId()) {
-            throw new NotFoundException();
-        }
-        $wishlist = $this->_getWishlist($item->getWishlistId());
-        if (!$wishlist) {
-            throw new NotFoundException();
-        }
-        try {
-            $item->delete();
-            $wishlist->save();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError(
-                __('An error occurred while deleting the item from wish list: %1', $e->getMessage())
-            );
-        } catch (\Exception $e) {
-            $this->messageManager->addError(__('An error occurred while deleting the item from wish list.'));
-        }
-
-        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-        $url = $this->_redirect->getRedirectUrl($this->_url->getUrl('*/*'));
-        $this->getResponse()->setRedirect($url);
-    }
-
-    /**
-     * Add wishlist item to shopping cart and remove from wishlist
-     *
-     * If Product has required options - item removed from wishlist and redirect
-     * to product view page with message about needed defined required options
-     *
-     * @return ResponseInterface
-     */
-    public function cartAction()
-    {
-        $itemId = (int)$this->getRequest()->getParam('item');
-
-        /* @var $item \Magento\Wishlist\Model\Item */
-        $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
-        if (!$item->getId()) {
-            return $this->_redirect('*/*');
-        }
-        $wishlist = $this->_getWishlist($item->getWishlistId());
-        if (!$wishlist) {
-            return $this->_redirect('*/*');
-        }
-
-        // Set qty
-        $qty = $this->getRequest()->getParam('qty');
-        if (is_array($qty)) {
-            if (isset($qty[$itemId])) {
-                $qty = $qty[$itemId];
-            } else {
-                $qty = 1;
-            }
-        }
-        $qty = $this->_processLocalizedQty($qty);
-        if ($qty) {
-            $item->setQty($qty);
-        }
-
-        /* @var $session \Magento\Framework\Session\Generic */
-        $session = $this->_objectManager->get('Magento\Wishlist\Model\Session');
-        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
-
-        $redirectUrl = $this->_url->getUrl('*/*');
-
-        try {
-            $options = $this->_objectManager->create(
-                'Magento\Wishlist\Model\Item\Option'
-            )->getCollection()->addItemFilter(
-                array($itemId)
-            );
-            $item->setOptions($options->getOptionsByItem($itemId));
-
-            $buyRequest = $this->_objectManager->get(
-                'Magento\Catalog\Helper\Product'
-            )->addParamsToBuyRequest(
-                $this->getRequest()->getParams(),
-                array('current_config' => $item->getBuyRequest())
-            );
-
-            $item->mergeBuyRequest($buyRequest);
-            $item->addToCart($cart, true);
-            $cart->save()->getQuote()->collectTotals();
-            $wishlist->save();
-
-            if (!$cart->getQuote()->getHasError()) {
-                $message = __(
-                    'You added %1 to your shopping cart.',
-                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($item->getProduct()->getName())
-                );
-                $this->messageManager->addSuccess($message);
-            }
-
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-            if ($this->_objectManager->get('Magento\Checkout\Helper\Cart')->getShouldRedirectToCart()) {
-                $redirectUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
-            } else {
-                $refererUrl = $this->_redirect->getRefererUrl();
-                if ($refererUrl &&
-                    ($refererUrl != $this->_objectManager->get('Magento\Framework\UrlInterface')
-                            ->getUrl('*/*/configure/', array('id' => $item->getId()))
-                    )
-                ) {
-                    $redirectUrl = $refererUrl;
-                }
-            }
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            if ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_NOT_SALABLE) {
-                $this->messageManager->addError(__('This product(s) is out of stock.'));
-            } elseif ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_HAS_REQUIRED_OPTIONS) {
-                $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl('*/*/configure/', array('id' => $item->getId()));
-            } else {
-                $this->messageManager->addNotice($e->getMessage());
-                $redirectUrl = $this->_url->getUrl('*/*/configure/', array('id' => $item->getId()));
-            }
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('Cannot add item to shopping cart'));
-        }
-
-        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-        return $this->getResponse()->setRedirect($redirectUrl);
-    }
-
-    /**
-     * Add cart item to wishlist and remove from cart
-     *
-     * @return \Zend_Controller_Response_Abstract
-     * @throws NotFoundException
-     */
-    public function fromcartAction()
-    {
-        $wishlist = $this->_getWishlist();
-        if (!$wishlist) {
-            throw new NotFoundException();
-        }
-        $itemId = (int)$this->getRequest()->getParam('item');
-
-        /* @var \Magento\Checkout\Model\Cart $cart */
-        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
-        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
-
-        try {
-            $item = $cart->getQuote()->getItemById($itemId);
-            if (!$item) {
-                throw new \Magento\Framework\Model\Exception(__("The requested cart item doesn't exist."));
-            }
-
-            $productId = $item->getProductId();
-            $buyRequest = $item->getBuyRequest();
-
-            $wishlist->addNewItem($productId, $buyRequest);
-
-            $productIds[] = $productId;
-            $cart->getQuote()->removeItem($itemId);
-            $cart->save();
-            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-            $productName = $this->_objectManager->get('Magento\Framework\Escaper')
-                ->escapeHtml($item->getProduct()->getName());
-            $wishlistName = $this->_objectManager->get('Magento\Framework\Escaper')
-                ->escapeHtml($wishlist->getName());
-            $this->messageManager->addSuccess(__("%1 has been moved to wish list %2", $productName, $wishlistName));
-            $wishlist->save();
-        } catch (\Magento\Framework\Model\Exception $e) {
-            $this->messageManager->addError($e->getMessage());
-        } catch (\Exception $e) {
-            $this->messageManager->addException($e, __('We can\'t move the item to the wish list.'));
-        }
-
-        return $this->getResponse()->setRedirect(
-            $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl()
-        );
-    }
-
-    /**
-     * Prepare wishlist for share
-     *
-     * @return void
-     */
-    public function shareAction()
-    {
-        $this->_getWishlist();
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
-    /**
-     * Share wishlist
-     *
-     * @return ResponseInterface|void
-     * @throws NotFoundException
-     */
-    public function sendAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            return $this->_redirect('*/*/');
-        }
-
-        $wishlist = $this->_getWishlist();
-        if (!$wishlist) {
-            throw new NotFoundException();
-        }
-
-        $sharingLimit = $this->_wishlistConfig->getSharingEmailLimit();
-        $textLimit = $this->_wishlistConfig->getSharingTextLimit();
-        $emailsLeft = $sharingLimit - $wishlist->getShared();
-        $emails = explode(',', $this->getRequest()->getPost('emails'));
-        $error = false;
-        $message = (string)$this->getRequest()->getPost('message');
-        if (strlen($message) > $textLimit) {
-            $error = __('Message length must not exceed %1 symbols', $textLimit);
-        } else {
-            $message = nl2br(htmlspecialchars($message));
-            if (empty($emails)) {
-                $error = __('Email address can\'t be empty.');
-            } else {
-                if (count($emails) > $emailsLeft) {
-                    $error = __('This wishlist can be shared %1 more times.', $emailsLeft);
-                } else {
-                    foreach ($emails as $index => $email) {
-                        $email = trim($email);
-                        if (!\Zend_Validate::is($email, 'EmailAddress')) {
-                            $error = __('Please input a valid email address.');
-                            break;
-                        }
-                        $emails[$index] = $email;
-                    }
-                }
-            }
-        }
-
-        if ($error) {
-            $this->messageManager->addError($error);
-            $this->_objectManager->get(
-                'Magento\Wishlist\Model\Session'
-            )->setSharingForm(
-                $this->getRequest()->getPost()
-            );
-            $this->_redirect('*/*/share');
-            return;
-        }
-
-        $this->inlineTranslation->suspend();
-
-        $sent = 0;
-
-        try {
-            $customer = $this->_customerSession->getCustomerDataObject();
-            $customerName = $this->_customerHelperView->getCustomerName($customer);
-            /*if share rss added rss feed to email template*/
-            if ($this->getRequest()->getParam('rss_url')) {
-                $rss_url = $this->_view->getLayout()->createBlock(
-                    'Magento\Wishlist\Block\Share\Email\Rss'
-                )->setWishlistId(
-                    $wishlist->getId()
-                )->toHtml();
-                $message .= $rss_url;
-            }
-            $wishlistBlock = $this->_view->getLayout()->createBlock(
-                'Magento\Wishlist\Block\Share\Email\Items'
-            )->toHtml();
-
-            $emails = array_unique($emails);
-            $sharingCode = $wishlist->getSharingCode();
-
-            try {
-                $scopeConfig = $this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
-                $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
-                foreach ($emails as $email) {
-                    $transport = $this->_transportBuilder->setTemplateIdentifier(
-                        $scopeConfig->getValue(
-                            'wishlist/email/email_template',
-                            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                        )
-                    )->setTemplateOptions(
-                        array(
-                            'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
-                            'store' => $storeManager->getStore()->getStoreId()
-                        )
-                    )->setTemplateVars(
-                        array(
-                            'customer' => $customer,
-                            'customerName' => $customerName,
-                            'salable' => $wishlist->isSalable() ? 'yes' : '',
-                            'items' => $wishlistBlock,
-                            'addAllLink' => $this->_url->getUrl('*/shared/allcart', array('code' => $sharingCode)),
-                            'viewOnSiteLink' => $this->_url->getUrl('*/shared/index', array('code' => $sharingCode)),
-                            'message' => $message,
-                            'store' => $storeManager->getStore()
-                        )
-                    )->setFrom(
-                        $scopeConfig->getValue(
-                            'wishlist/email/email_identity',
-                            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
-                        )
-                    )->addTo(
-                        $email
-                    )->getTransport();
-
-                    $transport->sendMessage();
-
-                    $sent++;
-                }
-            } catch (\Exception $e) {
-                $wishlist->setShared($wishlist->getShared() + $sent);
-                $wishlist->save();
-                throw $e;
-            }
-            $wishlist->setShared($wishlist->getShared() + $sent);
-            $wishlist->save();
-
-            $this->inlineTranslation->resume();
-
-            $this->_eventManager->dispatch('wishlist_share', array('wishlist' => $wishlist));
-            $this->messageManager->addSuccess(__('Your wish list has been shared.'));
-            $this->_redirect('*/*', array('wishlist_id' => $wishlist->getId()));
-        } catch (\Exception $e) {
-            $this->inlineTranslation->resume();
-            $this->messageManager->addError($e->getMessage());
-            $this->_objectManager->get(
-                'Magento\Wishlist\Model\Session'
-            )->setSharingForm(
-                $this->getRequest()->getPost()
-            );
-            $this->_redirect('*/*/share');
-        }
-    }
-
-    /**
-     * Custom options download action
-     *
-     * @return void
-     */
-    public function downloadCustomOptionAction()
-    {
-        $option = $this->_objectManager->create(
-            'Magento\Wishlist\Model\Item\Option'
-        )->load(
-            $this->getRequest()->getParam('id')
-        );
-
-        if (!$option->getId()) {
-            return $this->_forward('noroute');
-        }
-
-        $optionId = null;
-        if (strpos($option->getCode(), \Magento\Catalog\Model\Product\Type\AbstractType::OPTION_PREFIX) === 0) {
-            $optionId = str_replace(
-                \Magento\Catalog\Model\Product\Type\AbstractType::OPTION_PREFIX,
-                '',
-                $option->getCode()
-            );
-            if ((int)$optionId != $optionId) {
-                return $this->_forward('noroute');
-            }
-        }
-        $productOption = $this->_objectManager->create('Magento\Catalog\Model\Product\Option')->load($optionId);
-
-        if (!$productOption ||
-            !$productOption->getId() ||
-            $productOption->getProductId() != $option->getProductId() ||
-            $productOption->getType() != 'file'
-        ) {
-            return $this->_forward('noroute');
-        }
-
-        try {
-            $info = unserialize($option->getValue());
-            $filePath = $this->_objectManager->get(
-                'Magento\Framework\App\Filesystem'
-            )->getPath(
-                \Magento\Framework\App\Filesystem::ROOT_DIR
-            ) . $info['quote_path'];
-            $secretKey = $this->getRequest()->getParam('key');
-
-            if ($secretKey == $info['secret_key']) {
-                $this->_fileResponseFactory->create(
-                    $info['title'],
-                    array('value' => $filePath, 'type' => 'filename'),
-                    \Magento\Framework\App\Filesystem::ROOT_DIR
-                );
-            }
-        } catch (\Exception $e) {
-            $this->_forward('noroute');
-        }
-        exit(0);
-    }
-
-    /**
-     * Add all items from wishlist to shopping cart
-     *
-     * @return void
-     */
-    public function allcartAction()
-    {
-        if (!$this->_formKeyValidator->validate($this->getRequest())) {
-            $this->_forward('noroute');
-            return;
-        }
-
-        parent::allcartAction();
-    }
-}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Add.php b/app/code/Magento/Wishlist/Controller/Index/Add.php
new file mode 100644
index 0000000000000000000000000000000000000000..7fd54f2886465cc113f28d94846fc83d33f01c23
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Add.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+
+class Add extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $_customerSession;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+    ) {
+        $this->_customerSession = $customerSession;
+        $this->wishlistProvider = $wishlistProvider;
+        parent::__construct($context);
+    }
+
+    /**
+     * Adding new item
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            throw new NotFoundException();
+        }
+
+        $session = $this->_customerSession;
+
+        $requestParams = $this->getRequest()->getParams();
+
+        if ($session->getBeforeWishlistRequest()) {
+            $requestParams = $session->getBeforeWishlistRequest();
+            $session->unsBeforeWishlistRequest();
+        }
+
+        $productId = isset($requestParams['product']) ? (int)$requestParams['product'] : null;
+
+        if (!$productId) {
+            $this->_redirect('*/');
+            return;
+        }
+
+        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+        if (!$product->getId() || !$product->isVisibleInCatalog()) {
+            $this->messageManager->addError(__('We can\'t specify a product.'));
+            $this->_redirect('*/');
+            return;
+        }
+
+        try {
+            $buyRequest = new \Magento\Framework\Object($requestParams);
+
+            $result = $wishlist->addNewItem($product, $buyRequest);
+            if (is_string($result)) {
+                throw new \Magento\Framework\Model\Exception($result);
+            }
+            $wishlist->save();
+
+            $this->_eventManager->dispatch(
+                'wishlist_add_product',
+                array('wishlist' => $wishlist, 'product' => $product, 'item' => $result)
+            );
+
+            $referer = $session->getBeforeWishlistUrl();
+            if ($referer) {
+                $session->setBeforeWishlistUrl(null);
+            } else {
+                $referer = $this->_redirect->getRefererUrl();
+            }
+
+            /**
+             *  Set referer to avoid referring to the compare popup window
+             */
+            $session->setAddActionReferer($referer);
+
+            /** @var $helper \Magento\Wishlist\Helper\Data */
+            $helper = $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+            $message = __(
+                '%1 has been added to your wishlist. Click <a href="%2">here</a> to continue shopping.',
+                $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($product->getName()),
+                $this->_objectManager->get('Magento\Framework\Escaper')->escapeUrl($referer)
+            );
+            $this->messageManager->addSuccess($message);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError(
+                __('An error occurred while adding item to wish list: %1', $e->getMessage())
+            );
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while adding item to wish list.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+
+        $this->_redirect('*', array('wishlist_id' => $wishlist->getId()));
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Allcart.php b/app/code/Magento/Wishlist/Controller/Index/Allcart.php
new file mode 100644
index 0000000000000000000000000000000000000000..4721ccdae73a1a57e7b2c1e8500c77d374e92d68
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Allcart.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Core\App\Action\FormKeyValidator;
+use Magento\Framework\App\Action\Context;
+use Magento\Wishlist\Controller\WishlistProviderInterface;
+use Magento\Wishlist\Model\ItemCarrier;
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+
+class Allcart extends Action\Action implements IndexInterface
+{
+    /**
+     * @var WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Wishlist\Model\ItemCarrier
+     */
+    protected $itemCarrier;
+
+    /**
+     * @var \Magento\Core\App\Action\FormKeyValidator
+     */
+    protected $formKeyValidator;
+
+    /**
+     * @param Context $context
+     * @param WishlistProviderInterface $wishlistProvider
+     * @param FormKeyValidator $formKeyValidator
+     * @param ItemCarrier $itemCarrier
+     */
+    public function __construct(
+        Context $context,
+        WishlistProviderInterface $wishlistProvider,
+        FormKeyValidator $formKeyValidator,
+        ItemCarrier $itemCarrier
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        $this->formKeyValidator = $formKeyValidator;
+        $this->itemCarrier = $itemCarrier;
+        parent::__construct($context);
+    }
+
+    /**
+     * Add all items from wishlist to shopping cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        if (!$this->formKeyValidator->validate($this->getRequest())) {
+            $this->_forward('noroute');
+            return;
+        }
+
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            $this->_forward('noroute');
+            return;
+        }
+        $redirectUrl = $this->itemCarrier->moveAllToCart($wishlist, $this->getRequest()->getParam('qty'));
+        $this->getResponse()->setRedirect($redirectUrl);
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Cart.php b/app/code/Magento/Wishlist/Controller/Index/Cart.php
new file mode 100644
index 0000000000000000000000000000000000000000..3510c646a5b775db9778f2472091def48e29f8de
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Cart.php
@@ -0,0 +1,161 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\ResponseInterface;
+
+class Cart extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Wishlist\Model\LocaleQuantityProcessor
+     */
+    protected $quantityProcessor;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     * @param \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
+        \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        $this->quantityProcessor = $quantityProcessor;
+        parent::__construct($context);
+    }
+
+    /**
+     * Add wishlist item to shopping cart and remove from wishlist
+     *
+     * If Product has required options - item removed from wishlist and redirect
+     * to product view page with message about needed defined required options
+     *
+     * @return ResponseInterface
+     */
+    public function execute()
+    {
+        $itemId = (int)$this->getRequest()->getParam('item');
+
+        /* @var $item \Magento\Wishlist\Model\Item */
+        $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
+        if (!$item->getId()) {
+            return $this->_redirect('*/*');
+        }
+        $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
+        if (!$wishlist) {
+            return $this->_redirect('*/*');
+        }
+
+        // Set qty
+        $qty = $this->getRequest()->getParam('qty');
+        if (is_array($qty)) {
+            if (isset($qty[$itemId])) {
+                $qty = $qty[$itemId];
+            } else {
+                $qty = 1;
+            }
+        }
+        $qty = $this->quantityProcessor->process($qty);
+        if ($qty) {
+            $item->setQty($qty);
+        }
+
+        /* @var $session \Magento\Framework\Session\Generic */
+        $session = $this->_objectManager->get('Magento\Wishlist\Model\Session');
+        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
+
+        $redirectUrl = $this->_url->getUrl('*/*');
+
+        try {
+            $options = $this->_objectManager->create(
+                'Magento\Wishlist\Model\Item\Option'
+            )->getCollection()->addItemFilter(
+                array($itemId)
+            );
+            $item->setOptions($options->getOptionsByItem($itemId));
+
+            $buyRequest = $this->_objectManager->get(
+                'Magento\Catalog\Helper\Product'
+            )->addParamsToBuyRequest(
+                $this->getRequest()->getParams(),
+                array('current_config' => $item->getBuyRequest())
+            );
+
+            $item->mergeBuyRequest($buyRequest);
+            $item->addToCart($cart, true);
+            $cart->save()->getQuote()->collectTotals();
+            $wishlist->save();
+
+            if (!$cart->getQuote()->getHasError()) {
+                $message = __(
+                    'You added %1 to your shopping cart.',
+                    $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($item->getProduct()->getName())
+                );
+                $this->messageManager->addSuccess($message);
+            }
+
+            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+
+            if ($this->_objectManager->get('Magento\Checkout\Helper\Cart')->getShouldRedirectToCart()) {
+                $redirectUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
+            } else {
+                $refererUrl = $this->_redirect->getRefererUrl();
+                if ($refererUrl &&
+                    ($refererUrl != $this->_objectManager->get('Magento\Framework\UrlInterface')
+                            ->getUrl('*/*/configure/', array('id' => $item->getId()))
+                    )
+                ) {
+                    $redirectUrl = $refererUrl;
+                }
+            }
+            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            if ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_NOT_SALABLE) {
+                $this->messageManager->addError(__('This product(s) is out of stock.'));
+            } elseif ($e->getCode() == \Magento\Wishlist\Model\Item::EXCEPTION_CODE_HAS_REQUIRED_OPTIONS) {
+                $this->messageManager->addNotice($e->getMessage());
+                $redirectUrl = $this->_url->getUrl('*/*/configure/', array('id' => $item->getId()));
+            } else {
+                $this->messageManager->addNotice($e->getMessage());
+                $redirectUrl = $this->_url->getUrl('*/*/configure/', array('id' => $item->getId()));
+            }
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Cannot add item to shopping cart'));
+        }
+
+        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+
+        return $this->getResponse()->setRedirect($redirectUrl);
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Configure.php b/app/code/Magento/Wishlist/Controller/Index/Configure.php
new file mode 100644
index 0000000000000000000000000000000000000000..70448dd76cca06860a9d1a567520db90c8d1c13a
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Configure.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+
+class Configure extends Action\Action implements IndexInterface
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     * @param \Magento\Framework\Registry $coreRegistry
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
+        \Magento\Framework\Registry $coreRegistry
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        $this->_coreRegistry = $coreRegistry;
+        parent::__construct($context);
+    }
+
+    /**
+     * Action to reconfigure wishlist item
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('id');
+        try {
+            /* @var $item \Magento\Wishlist\Model\Item */
+            $item = $this->_objectManager->create('Magento\Wishlist\Model\Item');
+            $item->loadWithOptions($id);
+            if (!$item->getId()) {
+                throw new \Magento\Framework\Model\Exception(__('We can\'t load the wish list item.'));
+            }
+            $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
+            if (!$wishlist) {
+                throw new NotFoundException();
+            }
+
+            $this->_coreRegistry->register('wishlist_item', $item);
+
+            $params = new \Magento\Framework\Object();
+            $params->setCategoryId(false);
+            $params->setConfigureMode(true);
+            $buyRequest = $item->getBuyRequest();
+            if (!$buyRequest->getQty() && $item->getQty()) {
+                $buyRequest->setQty($item->getQty());
+            }
+            if ($buyRequest->getQty() && !$item->getQty()) {
+                $item->setQty($buyRequest->getQty());
+                $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+            }
+            $params->setBuyRequest($buyRequest);
+            $this->_objectManager->get(
+                'Magento\Catalog\Helper\Product\View'
+            )->prepareAndRender(
+                $item->getProductId(),
+                $this,
+                $params
+            );
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+            $this->_redirect('*');
+            return;
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('We can\'t configure the product.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+            $this->_redirect('*');
+            return;
+        }
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php
new file mode 100644
index 0000000000000000000000000000000000000000..9227ca996c81d546a457f1b7e1494eb8f3fa82cb
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/DownloadCustomOption.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+
+class DownloadCustomOption extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Framework\App\Response\Http\FileFactory
+     */
+    protected $_fileResponseFactory;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Framework\App\Response\Http\FileFactory $fileResponseFactory
+    ) {
+        $this->_fileResponseFactory = $fileResponseFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * Custom options download action
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $option = $this->_objectManager->create(
+            'Magento\Wishlist\Model\Item\Option'
+        )->load(
+            $this->getRequest()->getParam('id')
+        );
+
+        if (!$option->getId()) {
+            return $this->_forward('noroute');
+        }
+
+        $optionId = null;
+        if (strpos($option->getCode(), \Magento\Catalog\Model\Product\Type\AbstractType::OPTION_PREFIX) === 0) {
+            $optionId = str_replace(
+                \Magento\Catalog\Model\Product\Type\AbstractType::OPTION_PREFIX,
+                '',
+                $option->getCode()
+            );
+            if ((int)$optionId != $optionId) {
+                return $this->_forward('noroute');
+            }
+        }
+        $productOption = $this->_objectManager->create('Magento\Catalog\Model\Product\Option')->load($optionId);
+
+        if (!$productOption ||
+            !$productOption->getId() ||
+            $productOption->getProductId() != $option->getProductId() ||
+            $productOption->getType() != 'file'
+        ) {
+            return $this->_forward('noroute');
+        }
+
+        try {
+            $info = unserialize($option->getValue());
+            $filePath = $this->_objectManager->get(
+                'Magento\Framework\App\Filesystem'
+            )->getPath(
+                \Magento\Framework\App\Filesystem::ROOT_DIR
+            ) . $info['quote_path'];
+            $secretKey = $this->getRequest()->getParam('key');
+
+            if ($secretKey == $info['secret_key']) {
+                $this->_fileResponseFactory->create(
+                    $info['title'],
+                    array('value' => $filePath, 'type' => 'filename'),
+                    \Magento\Framework\App\Filesystem::ROOT_DIR
+                );
+            }
+        } catch (\Exception $e) {
+            $this->_forward('noroute');
+        }
+        exit(0);
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Fromcart.php b/app/code/Magento/Wishlist/Controller/Index/Fromcart.php
new file mode 100644
index 0000000000000000000000000000000000000000..115ee047a8f3cf76e9fd0c7e331c68fd4f5d6929
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Fromcart.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+
+class Fromcart extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        parent::__construct($context);
+    }
+
+    /**
+     * Add cart item to wishlist and remove from cart
+     *
+     * @return \Zend_Controller_Response_Abstract
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            throw new NotFoundException();
+        }
+        $itemId = (int)$this->getRequest()->getParam('item');
+
+        /* @var \Magento\Checkout\Model\Cart $cart */
+        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
+        $session = $this->_objectManager->get('Magento\Checkout\Model\Session');
+
+        try {
+            $item = $cart->getQuote()->getItemById($itemId);
+            if (!$item) {
+                throw new \Magento\Framework\Model\Exception(__("The requested cart item doesn't exist."));
+            }
+
+            $productId = $item->getProductId();
+            $buyRequest = $item->getBuyRequest();
+
+            $wishlist->addNewItem($productId, $buyRequest);
+
+            $productIds[] = $productId;
+            $cart->getQuote()->removeItem($itemId);
+            $cart->save();
+            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+            $productName = $this->_objectManager->get('Magento\Framework\Escaper')
+                ->escapeHtml($item->getProduct()->getName());
+            $wishlistName = $this->_objectManager->get('Magento\Framework\Escaper')
+                ->escapeHtml($wishlist->getName());
+            $this->messageManager->addSuccess(__("%1 has been moved to wish list %2", $productName, $wishlistName));
+            $wishlist->save();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('We can\'t move the item to the wish list.'));
+        }
+
+        return $this->getResponse()->setRedirect(
+            $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl()
+        );
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Index.php b/app/code/Magento/Wishlist/Controller/Index/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..0454cfe1f7d0cce16a0dd893f23f19a7f7d38d62
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Index.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+
+class Index extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $_customerSession;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+    ) {
+        $this->_customerSession = $customerSession;
+        $this->wishlistProvider = $wishlistProvider;
+        parent::__construct($context);
+    }
+
+    /**
+     * Display customer wishlist
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        if (!$this->wishlistProvider->getWishlist()) {
+            throw new NotFoundException();
+        }
+        $this->_view->loadLayout();
+
+        $session = $this->_customerSession;
+        $block = $this->_view->getLayout()->getBlock('customer.wishlist');
+        $referer = $session->getAddActionReferer(true);
+        if ($block) {
+            $block->setRefererUrl($this->_redirect->getRefererUrl());
+            if ($referer) {
+                $block->setRefererUrl($referer);
+            }
+        }
+
+        $this->_view->getLayout()->initMessages();
+
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Plugin.php b/app/code/Magento/Wishlist/Controller/Index/Plugin.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b4c55b4db2561c943f8baea9d018b4fa6b8f0a5
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Plugin.php
@@ -0,0 +1,94 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Customer\Model\Session as CustomerSession;
+use Magento\Framework\App\Action\NotFoundException;
+use Magento\Framework\App\Config\ScopeConfigInterface;
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\Response\RedirectInterface;
+
+class Plugin
+{
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Wishlist\Model\AuthenticationStateInterface
+     */
+    protected $authenticationState;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface
+     */
+    protected $config;
+
+    /**
+     * @var \Magento\Framework\App\Response\RedirectInterface
+     */
+    protected $redirector;
+
+    /**
+     * @param CustomerSession $customerSession
+     * @param \Magento\Wishlist\Model\AuthenticationStateInterface $authenticationState
+     * @param ScopeConfigInterface $config
+     * @param RedirectInterface $redirector
+     */
+    public function __construct(
+        CustomerSession $customerSession,
+        \Magento\Wishlist\Model\AuthenticationStateInterface $authenticationState,
+        ScopeConfigInterface $config,
+        RedirectInterface $redirector
+    ) {
+        $this->customerSession = $customerSession;
+        $this->authenticationState = $authenticationState;
+        $this->config = $config;
+        $this->redirector = $redirector;
+    }
+
+    /**
+     * Perform customer authentication and wishlist feature state checks
+     *
+     * @param \Magento\Framework\App\ActionInterface $subject
+     * @param RequestInterface $request
+     * @return void
+     * @throws \Magento\Framework\App\Action\NotFoundException
+     */
+    public function beforeDispatch(\Magento\Framework\App\ActionInterface $subject, RequestInterface $request)
+    {
+        if ($this->authenticationState->isEnabled() && !$this->customerSession->authenticate($subject)) {
+            $subject->getActionFlag()->set('', 'no-dispatch', true);
+            if (!$this->customerSession->getBeforeWishlistUrl()) {
+                $this->customerSession->setBeforeWishlistUrl($this->redirector->getRefererUrl());
+            }
+            $this->customerSession->setBeforeWishlistRequest($request->getParams());
+        }
+        if (!$this->config->isSetFlag('wishlist/general/active')) {
+            throw new NotFoundException();
+        }
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Remove.php b/app/code/Magento/Wishlist/Controller/Index/Remove.php
new file mode 100644
index 0000000000000000000000000000000000000000..a508e995fda3947e375ca53d17f417a5b34a3ff7
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Remove.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+
+class Remove extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        parent::__construct($context);
+    }
+
+    /**
+     * Remove item
+     *
+     * @return void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        $id = (int)$this->getRequest()->getParam('item');
+        $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($id);
+        if (!$item->getId()) {
+            throw new NotFoundException();
+        }
+        $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
+        if (!$wishlist) {
+            throw new NotFoundException();
+        }
+        try {
+            $item->delete();
+            $wishlist->save();
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError(
+                __('An error occurred while deleting the item from wish list: %1', $e->getMessage())
+            );
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while deleting the item from wish list.'));
+        }
+
+        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+
+        $url = $this->_redirect->getRedirectUrl($this->_url->getUrl('*/*'));
+        $this->getResponse()->setRedirect($url);
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Send.php b/app/code/Magento/Wishlist/Controller/Index/Send.php
new file mode 100644
index 0000000000000000000000000000000000000000..196242e3f4c803316c234a668e51dd4f332046d8
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Send.php
@@ -0,0 +1,240 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+use Magento\Framework\App\ResponseInterface;
+
+class Send extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Customer\Helper\View
+     */
+    protected $_customerHelperView;
+
+    /**
+     * @var \Magento\Framework\Translate\Inline\StateInterface
+     */
+    protected $inlineTranslation;
+
+    /**
+     * @var \Magento\Framework\Mail\Template\TransportBuilder
+     */
+    protected $_transportBuilder;
+
+    /**
+     * @var \Magento\Wishlist\Model\Config
+     */
+    protected $_wishlistConfig;
+
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $_customerSession;
+
+    /**
+     * @var \Magento\Core\App\Action\FormKeyValidator
+     */
+    protected $_formKeyValidator;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     * @param \Magento\Wishlist\Model\Config $wishlistConfig
+     * @param \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder
+     * @param \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation
+     * @param \Magento\Customer\Helper\View $customerHelperView
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
+        \Magento\Wishlist\Model\Config $wishlistConfig,
+        \Magento\Framework\Mail\Template\TransportBuilder $transportBuilder,
+        \Magento\Framework\Translate\Inline\StateInterface $inlineTranslation,
+        \Magento\Customer\Helper\View $customerHelperView
+    ) {
+        $this->_formKeyValidator = $formKeyValidator;
+        $this->_customerSession = $customerSession;
+        $this->wishlistProvider = $wishlistProvider;
+        $this->_wishlistConfig = $wishlistConfig;
+        $this->_transportBuilder = $transportBuilder;
+        $this->inlineTranslation = $inlineTranslation;
+        $this->_customerHelperView = $customerHelperView;
+        parent::__construct($context);
+    }
+
+    /**
+     * Share wishlist
+     *
+     * @return ResponseInterface|void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            return $this->_redirect('*/*/');
+        }
+
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            throw new NotFoundException();
+        }
+
+        $sharingLimit = $this->_wishlistConfig->getSharingEmailLimit();
+        $textLimit = $this->_wishlistConfig->getSharingTextLimit();
+        $emailsLeft = $sharingLimit - $wishlist->getShared();
+        $emails = explode(',', $this->getRequest()->getPost('emails'));
+        $error = false;
+        $message = (string)$this->getRequest()->getPost('message');
+        if (strlen($message) > $textLimit) {
+            $error = __('Message length must not exceed %1 symbols', $textLimit);
+        } else {
+            $message = nl2br(htmlspecialchars($message));
+            if (empty($emails)) {
+                $error = __('Email address can\'t be empty.');
+            } else {
+                if (count($emails) > $emailsLeft) {
+                    $error = __('This wishlist can be shared %1 more times.', $emailsLeft);
+                } else {
+                    foreach ($emails as $index => $email) {
+                        $email = trim($email);
+                        if (!\Zend_Validate::is($email, 'EmailAddress')) {
+                            $error = __('Please input a valid email address.');
+                            break;
+                        }
+                        $emails[$index] = $email;
+                    }
+                }
+            }
+        }
+
+        if ($error) {
+            $this->messageManager->addError($error);
+            $this->_objectManager->get(
+                'Magento\Wishlist\Model\Session'
+            )->setSharingForm(
+                $this->getRequest()->getPost()
+            );
+            $this->_redirect('*/*/share');
+            return;
+        }
+
+        $this->inlineTranslation->suspend();
+
+        $sent = 0;
+
+        try {
+            $customer = $this->_customerSession->getCustomerDataObject();
+            $customerName = $this->_customerHelperView->getCustomerName($customer);
+            /*if share rss added rss feed to email template*/
+            if ($this->getRequest()->getParam('rss_url')) {
+                $rss_url = $this->_view->getLayout()->createBlock(
+                    'Magento\Wishlist\Block\Share\Email\Rss'
+                )->setWishlistId(
+                    $wishlist->getId()
+                )->toHtml();
+                $message .= $rss_url;
+            }
+            $wishlistBlock = $this->_view->getLayout()->createBlock(
+                'Magento\Wishlist\Block\Share\Email\Items'
+            )->toHtml();
+
+            $emails = array_unique($emails);
+            $sharingCode = $wishlist->getSharingCode();
+
+            try {
+                $scopeConfig = $this->_objectManager->get('Magento\Framework\App\Config\ScopeConfigInterface');
+                $storeManager = $this->_objectManager->get('Magento\Store\Model\StoreManagerInterface');
+                foreach ($emails as $email) {
+                    $transport = $this->_transportBuilder->setTemplateIdentifier(
+                        $scopeConfig->getValue(
+                            'wishlist/email/email_template',
+                            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                        )
+                    )->setTemplateOptions(
+                        array(
+                            'area' => \Magento\Framework\App\Area::AREA_FRONTEND,
+                            'store' => $storeManager->getStore()->getStoreId()
+                        )
+                    )->setTemplateVars(
+                        array(
+                            'customer' => $customer,
+                            'customerName' => $customerName,
+                            'salable' => $wishlist->isSalable() ? 'yes' : '',
+                            'items' => $wishlistBlock,
+                            'addAllLink' => $this->_url->getUrl('*/shared/allcart', array('code' => $sharingCode)),
+                            'viewOnSiteLink' => $this->_url->getUrl('*/shared/index', array('code' => $sharingCode)),
+                            'message' => $message,
+                            'store' => $storeManager->getStore()
+                        )
+                    )->setFrom(
+                        $scopeConfig->getValue(
+                            'wishlist/email/email_identity',
+                            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
+                        )
+                    )->addTo(
+                        $email
+                    )->getTransport();
+
+                    $transport->sendMessage();
+
+                    $sent++;
+                }
+            } catch (\Exception $e) {
+                $wishlist->setShared($wishlist->getShared() + $sent);
+                $wishlist->save();
+                throw $e;
+            }
+            $wishlist->setShared($wishlist->getShared() + $sent);
+            $wishlist->save();
+
+            $this->inlineTranslation->resume();
+
+            $this->_eventManager->dispatch('wishlist_share', array('wishlist' => $wishlist));
+            $this->messageManager->addSuccess(__('Your wish list has been shared.'));
+            $this->_redirect('*/*', array('wishlist_id' => $wishlist->getId()));
+        } catch (\Exception $e) {
+            $this->inlineTranslation->resume();
+            $this->messageManager->addError($e->getMessage());
+            $this->_objectManager->get(
+                'Magento\Wishlist\Model\Session'
+            )->setSharingForm(
+                $this->getRequest()->getPost()
+            );
+            $this->_redirect('*/*/share');
+        }
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Share.php b/app/code/Magento/Wishlist/Controller/Index/Share.php
new file mode 100644
index 0000000000000000000000000000000000000000..6ca6d4638da99d1aae7c1a598e71f7a151086f7e
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Share.php
@@ -0,0 +1,43 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+
+class Share extends Action\Action implements IndexInterface
+{
+    /**
+     * Prepare wishlist for share
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/Update.php b/app/code/Magento/Wishlist/Controller/Index/Update.php
new file mode 100644
index 0000000000000000000000000000000000000000..36867b453d247fd7817ab03452551758515bbe31
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/Update.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\Action\NotFoundException;
+use Magento\Framework\App\ResponseInterface;
+
+class Update extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Core\App\Action\FormKeyValidator
+     */
+    protected $_formKeyValidator;
+
+    /**
+     * @var \Magento\Wishlist\Model\LocaleQuantityProcessor
+     */
+    protected $quantityProcessor;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     * @param \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider,
+        \Magento\Wishlist\Model\LocaleQuantityProcessor $quantityProcessor
+    ) {
+        $this->_formKeyValidator = $formKeyValidator;
+        $this->wishlistProvider = $wishlistProvider;
+        $this->quantityProcessor = $quantityProcessor;
+        parent::__construct($context);
+    }
+
+    /**
+     * Update wishlist item comments
+     *
+     * @return ResponseInterface|void
+     * @throws NotFoundException
+     */
+    public function execute()
+    {
+        if (!$this->_formKeyValidator->validate($this->getRequest())) {
+            return $this->_redirect('*/*/');
+        }
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            throw new NotFoundException();
+        }
+
+        $post = $this->getRequest()->getPost();
+        if ($post && isset($post['description']) && is_array($post['description'])) {
+            $updatedItems = 0;
+
+            foreach ($post['description'] as $itemId => $description) {
+                $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
+                if ($item->getWishlistId() != $wishlist->getId()) {
+                    continue;
+                }
+
+                // Extract new values
+                $description = (string)$description;
+
+                if ($description == $this->_objectManager->get('Magento\Wishlist\Helper\Data')->defaultCommentString()
+                ) {
+                    $description = '';
+                } elseif (!strlen($description)) {
+                    $description = $item->getDescription();
+                }
+
+                $qty = null;
+                if (isset($post['qty'][$itemId])) {
+                    $qty = $this->quantityProcessor->process($post['qty'][$itemId]);
+                }
+                if (is_null($qty)) {
+                    $qty = $item->getQty();
+                    if (!$qty) {
+                        $qty = 1;
+                    }
+                } elseif (0 == $qty) {
+                    try {
+                        $item->delete();
+                    } catch (\Exception $e) {
+                        $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                        $this->messageManager->addError(__('Can\'t delete item from wishlist'));
+                    }
+                }
+
+                // Check that we need to save
+                if ($item->getDescription() == $description && $item->getQty() == $qty) {
+                    continue;
+                }
+                try {
+                    $item->setDescription($description)->setQty($qty)->save();
+                    $updatedItems++;
+                } catch (\Exception $e) {
+                    $this->messageManager->addError(
+                        __(
+                            'Can\'t save description %1',
+                            $this->_objectManager->get('Magento\Framework\Escaper')->escapeHtml($description)
+                        )
+                    );
+                }
+            }
+
+            // save wishlist model for setting date of last update
+            if ($updatedItems) {
+                try {
+                    $wishlist->save();
+                    $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+                } catch (\Exception $e) {
+                    $this->messageManager->addError(__('Can\'t update wish list'));
+                }
+            }
+
+            if (isset($post['save_and_share'])) {
+                $this->_redirect('*/*/share', array('wishlist_id' => $wishlist->getId()));
+                return;
+            }
+        }
+        $this->_redirect('*', array('wishlist_id' => $wishlist->getId()));
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
new file mode 100644
index 0000000000000000000000000000000000000000..173d81663e3a7a84a3756ebea2c215ccb770879a
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Index/UpdateItemOptions.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Index;
+
+use Magento\Wishlist\Controller\IndexInterface;
+use Magento\Framework\App\Action;
+
+class UpdateItemOptions extends Action\Action implements IndexInterface
+{
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $_customerSession;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Wishlist\Controller\WishlistProviderInterface $wishlistProvider
+    ) {
+        $this->_customerSession = $customerSession;
+        $this->wishlistProvider = $wishlistProvider;
+        parent::__construct($context);
+    }
+
+    /**
+     * Action to accept new configuration for a wishlist item
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $productId = (int)$this->getRequest()->getParam('product');
+        if (!$productId) {
+            $this->_redirect('*/');
+            return;
+        }
+
+        $product = $this->_objectManager->create('Magento\Catalog\Model\Product')->load($productId);
+        if (!$product->getId() || !$product->isVisibleInCatalog()) {
+            $this->messageManager->addError(__('We can\'t specify a product.'));
+            $this->_redirect('*/');
+            return;
+        }
+
+        try {
+            $id = (int)$this->getRequest()->getParam('id');
+            /* @var \Magento\Wishlist\Model\Item */
+            $item = $this->_objectManager->create('Magento\Wishlist\Model\Item');
+            $item->load($id);
+            $wishlist = $this->wishlistProvider->getWishlist($item->getWishlistId());
+            if (!$wishlist) {
+                $this->_redirect('*/');
+                return;
+            }
+
+            $buyRequest = new \Magento\Framework\Object($this->getRequest()->getParams());
+
+            $wishlist->updateItem($id, $buyRequest)->save();
+
+            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+            $this->_eventManager->dispatch(
+                'wishlist_update_item',
+                array('wishlist' => $wishlist, 'product' => $product, 'item' => $wishlist->getItem($id))
+            );
+
+            $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
+
+            $message = __('%1 has been updated in your wish list.', $product->getName());
+            $this->messageManager->addSuccess($message);
+        } catch (\Magento\Framework\Model\Exception $e) {
+            $this->messageManager->addError($e->getMessage());
+        } catch (\Exception $e) {
+            $this->messageManager->addError(__('An error occurred while updating wish list.'));
+            $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+        }
+        $this->_redirect('*/*', array('wishlist_id' => $wishlist->getId()));
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/IndexInterface.php b/app/code/Magento/Wishlist/Controller/IndexInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..7b4af0e93c74e5c04d591620da0ab1df79eab224
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/IndexInterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller;
+
+use \Magento\Catalog\Controller\Product\View\ViewInterface;
+
+interface IndexInterface extends \Magento\Framework\App\ActionInterface, ViewInterface
+{
+}
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Allcart.php b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c0cfa4b87b955031faa21a5e0bcc25240bf8975
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Shared/Allcart.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Shared;
+
+use Magento\Framework\App\Action\Context;
+use Magento\Wishlist\Model\ItemCarrier;
+
+class Allcart extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * @var WishlistProvider
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Wishlist\Model\ItemCarrier
+     */
+    protected $itemCarrier;
+
+    /**
+     * @param Context $context
+     * @param WishlistProvider $wishlistProvider
+     * @param ItemCarrier $itemCarrier
+     */
+    public function __construct(
+        Context $context,
+        WishlistProvider $wishlistProvider,
+        ItemCarrier $itemCarrier
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        $this->itemCarrier = $itemCarrier;
+        parent::__construct($context);
+    }
+
+    /**
+     * Add all items from wishlist to shopping cart
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $wishlist = $this->wishlistProvider->getWishlist();
+        if (!$wishlist) {
+            $this->_forward('noroute');
+            return;
+        }
+        $redirectUrl = $this->itemCarrier->moveAllToCart($wishlist, $this->getRequest()->getParam('qty'));
+        $this->getResponse()->setRedirect($redirectUrl);
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Shared.php b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
similarity index 52%
rename from app/code/Magento/Wishlist/Controller/Shared.php
rename to app/code/Magento/Wishlist/Controller/Shared/Cart.php
index 22684d613ceb63711af6ce1b4c1f9db5944829a0..e2dbfa02dbc7daf273eb77fa12bef17c66f29d1a 100644
--- a/app/code/Magento/Wishlist/Controller/Shared.php
+++ b/app/code/Magento/Wishlist/Controller/Shared/Cart.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,86 +22,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Wishlist\Controller\Shared;
 
-
-/**
- * Wishlist shared items controllers
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\Wishlist\Controller;
-
-class Shared extends AbstractController
+class Cart extends \Magento\Framework\App\Action\Action
 {
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Framework\App\Action\Context $context
-     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Framework\Registry $coreRegistry
-     */
-    public function __construct(
-        \Magento\Framework\App\Action\Context $context,
-        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Framework\Registry $coreRegistry
-    ) {
-        $this->_coreRegistry = $coreRegistry;
-        parent::__construct($context, $formKeyValidator, $customerSession);
-    }
-
-    /**
-     * Retrieve wishlist instance by requested code
-     *
-     * @return \Magento\Wishlist\Model\Wishlist|false
-     */
-    protected function _getWishlist()
-    {
-        $code = (string)$this->getRequest()->getParam('code');
-        if (empty($code)) {
-            return false;
-        }
-
-        $wishlist = $this->_objectManager->create('Magento\Wishlist\Model\Wishlist')->loadByCode($code);
-        if (!$wishlist->getId()) {
-            return false;
-        }
-
-        $this->_objectManager->get('Magento\Checkout\Model\Session')->setSharedWishlist($code);
-
-        return $wishlist;
-    }
-
-    /**
-     * Shared wishlist view page
-     *
-     * @return void
-     */
-    public function indexAction()
-    {
-        $wishlist = $this->_getWishlist();
-        $customerId = $this->_customerSession->getCustomerId();
-
-        if ($wishlist && $wishlist->getCustomerId() && $wishlist->getCustomerId() == $customerId) {
-            $this->getResponse()->setRedirect(
-                $this->_objectManager->get('Magento\Wishlist\Helper\Data')->getListUrl($wishlist->getId())
-            );
-            return;
-        }
-
-        $this->_coreRegistry->register('shared_wishlist', $wishlist);
-
-        $this->_view->loadLayout();
-        $this->_view->getLayout()->initMessages();
-        $this->_view->renderLayout();
-    }
-
     /**
      * Add shared wishlist item to shopping cart
      *
@@ -109,7 +34,7 @@ class Shared extends AbstractController
      *
      * @return \Zend_Controller_Response_Abstract
      */
-    public function cartAction()
+    public function execute()
     {
         $itemId = (int)$this->getRequest()->getParam('item');
 
@@ -117,8 +42,6 @@ class Shared extends AbstractController
         $item = $this->_objectManager->create('Magento\Wishlist\Model\Item')->load($itemId);
 
 
-        /* @var $session \Magento\Framework\Session\Generic */
-        $session = $this->_objectManager->get('Magento\Wishlist\Model\Session');
         $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
 
         $redirectUrl = $this->_redirect->getRefererUrl();
diff --git a/app/code/Magento/Wishlist/Controller/Shared/Index.php b/app/code/Magento/Wishlist/Controller/Shared/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..b5b4da34ea922d879ebd4af42ad1a60a20710d12
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Shared/Index.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Shared;
+
+use Magento\Framework\App\Action\AbstractAction;
+use Magento\Framework\App\Action\Action;
+use Magento\Framework\App\Action\Context;
+use Magento\Wishlist\Controller\WishlistProviderInterface;
+
+class Index extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry = null;
+
+    /**
+     * @var WishlistProvider
+     */
+    protected $wishlistProvider;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @param Context $context
+     * @param WishlistProvider $wishlistProvider
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Customer\Model\Session $customerSession
+     */
+    public function __construct(
+        Context $context,
+        WishlistProvider $wishlistProvider,
+        \Magento\Framework\Registry $registry,
+        \Magento\Customer\Model\Session $customerSession
+    ) {
+        $this->wishlistProvider = $wishlistProvider;
+        $this->registry = $registry;
+        $this->customerSession = $customerSession;
+        parent::__construct($context);
+    }
+
+    /**
+     * Shared wishlist view page
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $wishlist = $this->wishlistProvider->getWishlist();
+        $customerId = $this->customerSession->getCustomerId();
+
+        if ($wishlist && $wishlist->getCustomerId() && $wishlist->getCustomerId() == $customerId) {
+            $this->getResponse()->setRedirect(
+                $this->_objectManager->get('Magento\Wishlist\Helper\Data')->getListUrl($wishlist->getId())
+            );
+            return;
+        }
+
+        $this->registry->register('shared_wishlist', $wishlist);
+
+        $this->_view->loadLayout();
+        $this->_view->getLayout()->initMessages();
+        $this->_view->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/Shared/WishlistProvider.php b/app/code/Magento/Wishlist/Controller/Shared/WishlistProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d448a911c3bc3619b201ea41a4c862b201adab4
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/Shared/WishlistProvider.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller\Shared;
+
+use Magento\Wishlist\Controller\WishlistProviderInterface;
+
+class WishlistProvider implements WishlistProviderInterface
+{
+    /**
+     * @var \Magento\Framework\App\RequestInterface
+     */
+    protected $request;
+
+    /**
+     * @var \Magento\Wishlist\Model\WishlistFactory
+     */
+    protected $wishlistFactory;
+
+    /**
+     * @var \Magento\Checkout\Model\Session
+     */
+    protected $checkoutSession;
+
+    /**
+     * @var \Magento\Wishlist\Model\Wishlist
+     */
+    protected $wishlist;
+
+    /**
+     * @param \Magento\Framework\App\RequestInterface $request
+     * @param \Magento\Wishlist\Model\WishlistFactory $wishlistFactory
+     * @param \Magento\Checkout\Model\Session $checkoutSession
+     */
+    public function __construct(
+        \Magento\Framework\App\RequestInterface $request,
+        \Magento\Wishlist\Model\WishlistFactory $wishlistFactory,
+        \Magento\Checkout\Model\Session $checkoutSession
+    ) {
+        $this->request = $request;
+        $this->wishlistFactory = $wishlistFactory;
+        $this->checkoutSession = $checkoutSession;
+    }
+
+    /**
+     * Retrieve current wishlist
+     * @param string $wishlistId
+     * @return \Magento\Wishlist\Model\Wishlist
+     */
+    public function getWishlist($wishlistId = null)
+    {
+        if ($this->wishlist) {
+            return $this->wishlist;
+        }
+        $code = (string)$this->request->getParam('code');
+        if (empty($code)) {
+            return false;
+        }
+
+        $wishlist = $this->wishlistFactory->create()->loadByCode($code);
+        if (!$wishlist->getId()) {
+            return false;
+        }
+
+        $this->checkoutSession->setSharedWishlist($code);
+        $this->wishlist = $wishlist;
+        return $wishlist;
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/WishlistProvider.php b/app/code/Magento/Wishlist/Controller/WishlistProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..5af58dd44f3c1dbd5675d6ff0912d8ff63d216a0
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/WishlistProvider.php
@@ -0,0 +1,111 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller;
+
+use Magento\Framework\App\RequestInterface;
+
+class WishlistProvider implements WishlistProviderInterface
+{
+    /**
+     * @var \Magento\Wishlist\Model\Wishlist
+     */
+    protected $wishlist;
+
+    /**
+     * @var \Magento\Wishlist\Model\WishlistFactory
+     */
+    protected $wishlistFactory;
+
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface
+     */
+    protected $request;
+
+    /**
+     * @param \Magento\Wishlist\Model\WishlistFactory $wishlistFactory
+     * @param \Magento\Customer\Model\Session $customerSession
+     * @param \Magento\Framework\Message\ManagerInterface $messageManager
+     * @param RequestInterface $request
+     */
+    public function __construct(
+        \Magento\Wishlist\Model\WishlistFactory $wishlistFactory,
+        \Magento\Customer\Model\Session $customerSession,
+        \Magento\Framework\Message\ManagerInterface $messageManager,
+        RequestInterface $request
+    ) {
+        $this->request = $request;
+        $this->wishlistFactory = $wishlistFactory;
+        $this->customerSession = $customerSession;
+        $this->messageManager = $messageManager;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getWishlist($wishlistId = null)
+    {
+        if ($this->wishlist) {
+            return $this->wishlist;
+        }
+        try {
+            if (!$wishlistId) {
+                $wishlistId = $this->request->getParam('wishlist_id');
+            }
+            $customerId = $this->customerSession->getCustomerId();
+            $wishlist = $this->wishlistFactory->create();
+            if ($wishlistId) {
+                $wishlist->load($wishlistId);
+            } else {
+                $wishlist->loadByCustomerId($customerId, true);
+            }
+
+            if (!$wishlist->getId() || $wishlist->getCustomerId() != $customerId) {
+                $wishlist = null;
+                throw new \Magento\Framework\Exception\NoSuchEntityException(
+                    __("The requested wish list doesn't exist.")
+                );
+            }
+
+        } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+            $this->messageManager->addError($e->getMessage());
+            return false;
+        } catch (\Exception $e) {
+            $this->messageManager->addException($e, __('Wish List could not be created.'));
+            return false;
+        }
+        $this->wishlist = $wishlist;
+        return $wishlist;
+    }
+}
diff --git a/app/code/Magento/Wishlist/Controller/WishlistProviderInterface.php b/app/code/Magento/Wishlist/Controller/WishlistProviderInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..67511ba1541ed74e6d899c68e12a48b1bf8ff64e
--- /dev/null
+++ b/app/code/Magento/Wishlist/Controller/WishlistProviderInterface.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Controller;
+
+interface WishlistProviderInterface
+{
+    /**
+     * Retrieve wishlist
+     *
+     * @param string $wishlistId
+     * @return \Magento\Wishlist\Model\Wishlist
+     */
+    public function getWishlist($wishlistId = null);
+}
diff --git a/app/code/Magento/Wishlist/Helper/Data.php b/app/code/Magento/Wishlist/Helper/Data.php
index cb01684a3b5c82d58ef7e1b53d5bc0346bc65ef1..f26539233ffa0b56e4fb302b6f5a1c883cc51b78 100644
--- a/app/code/Magento/Wishlist/Helper/Data.php
+++ b/app/code/Magento/Wishlist/Helper/Data.php
@@ -23,6 +23,8 @@
  */
 namespace Magento\Wishlist\Helper;
 
+use Magento\Wishlist\Controller\WishlistProviderInterface;
+
 /**
  * Wishlist Data Helper
  *
@@ -114,6 +116,11 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      */
     protected $_customerViewHelper;
 
+    /**
+     * @var \Magento\Wishlist\Controller\WishlistProviderInterface
+     */
+    protected $wishlistProvider;
+
     /**
      * @param \Magento\Framework\App\Helper\Context $context
      * @param \Magento\Core\Helper\Data $coreData
@@ -124,6 +131,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
      * @param \Magento\Store\Model\StoreManagerInterface $storeManager
      * @param \Magento\Core\Helper\PostData $postDataHelper
      * @param \Magento\Customer\Helper\View $customerViewHelper
+     * @param WishlistProviderInterface $wishlistProvider
      */
     public function __construct(
         \Magento\Framework\App\Helper\Context $context,
@@ -134,7 +142,8 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         \Magento\Wishlist\Model\WishlistFactory $wishlistFactory,
         \Magento\Store\Model\StoreManagerInterface $storeManager,
         \Magento\Core\Helper\PostData $postDataHelper,
-        \Magento\Customer\Helper\View $customerViewHelper
+        \Magento\Customer\Helper\View $customerViewHelper,
+        WishlistProviderInterface $wishlistProvider
     ) {
         $this->_coreRegistry = $coreRegistry;
         $this->_coreData = $coreData;
@@ -144,6 +153,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         $this->_storeManager = $storeManager;
         $this->_postDataHelper = $postDataHelper;
         $this->_customerViewHelper = $customerViewHelper;
+        $this->wishlistProvider = $wishlistProvider;
         parent::__construct($context);
     }
 
@@ -201,12 +211,13 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper
         if (is_null($this->_wishlist)) {
             if ($this->_coreRegistry->registry('shared_wishlist')) {
                 $this->_wishlist = $this->_coreRegistry->registry('shared_wishlist');
-            } elseif ($this->_coreRegistry->registry('wishlist')) {
-                $this->_wishlist = $this->_coreRegistry->registry('wishlist');
             } else {
-                $this->_wishlist = $this->_wishlistFactory->create();
-                if ($this->getCustomer()) {
-                    $this->_wishlist->loadByCustomerId($this->getCustomer()->getId());
+                $this->_wishlist = $this->wishlistProvider->getWishlist();
+                if (!$this->_wishlist) {
+                    $this->_wishlist = $this->_wishlistFactory->create();
+                    if ($this->getCustomer()) {
+                        $this->_wishlist->loadByCustomerId($this->getCustomer()->getId());
+                    }
                 }
             }
         }
diff --git a/app/code/Magento/Wishlist/Model/AuthenticationState.php b/app/code/Magento/Wishlist/Model/AuthenticationState.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0053d92b19a6725e2b885630ce6a9ed5b5384f8
--- /dev/null
+++ b/app/code/Magento/Wishlist/Model/AuthenticationState.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Model;
+
+class AuthenticationState implements AuthenticationStateInterface
+{
+    /**
+     * Is authentication enabled
+     *
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return true;
+    }
+}
diff --git a/app/code/Magento/Wishlist/Model/AuthenticationStateInterface.php b/app/code/Magento/Wishlist/Model/AuthenticationStateInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..c5b881b8ce9952fc684b354c90129aa78cc4aa10
--- /dev/null
+++ b/app/code/Magento/Wishlist/Model/AuthenticationStateInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Wishlist\Model;
+
+interface AuthenticationStateInterface
+{
+    /**
+     * Is authentication enabled
+     *
+     * @return bool
+     */
+    public function isEnabled();
+}
diff --git a/app/code/Magento/Wishlist/Controller/AbstractController.php b/app/code/Magento/Wishlist/Model/ItemCarrier.php
similarity index 61%
rename from app/code/Magento/Wishlist/Controller/AbstractController.php
rename to app/code/Magento/Wishlist/Model/ItemCarrier.php
index 96fc4e33f7ef711433a83d583246f076de26bf46..80e5c786496cc9d3650449d51ef447c9ff46c63e 100644
--- a/app/code/Magento/Wishlist/Controller/AbstractController.php
+++ b/app/code/Magento/Wishlist/Model/ItemCarrier.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,97 +22,116 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Wishlist\Controller;
+namespace Magento\Wishlist\Model;
+
+use Magento\Checkout\Model\Cart;
+use Magento\Customer\Model\Session;
+use Magento\Framework\App\Response\RedirectInterface;
+use Magento\Framework\Logger;
+use Magento\Framework\UrlInterface;
+use Magento\Wishlist\Helper\Data as WishlistHelper;
+use Magento\Checkout\Helper\Cart as CartHelper;
+use Magento\Framework\Message\ManagerInterface as MessageManager;
+
+class ItemCarrier
+{
+    /**
+     * @var \Magento\Customer\Model\Session
+     */
+    protected $customerSession;
 
-use Magento\Framework\App\Action\Context;
+    /**
+     * @var LocaleQuantityProcessor
+     */
+    protected $quantityProcessor;
 
-/**
- * Wishlist Abstract Front Controller Action
- */
-abstract class AbstractController extends \Magento\Framework\App\Action\Action
-{
     /**
-     * Filter to convert localized values to internal ones
-     *
-     * @var \Zend_Filter_LocalizedToNormalized
+     * @var \Magento\Checkout\Model\Cart
      */
-    protected $_localFilter = null;
+    protected $cart;
 
     /**
-     * @var \Magento\Core\App\Action\FormKeyValidator
+     * @var \Magento\Framework\Logger
      */
-    protected $_formKeyValidator;
+    protected $logger;
 
     /**
-     * @var \Magento\Customer\Model\Session
+     * @var \Magento\Wishlist\Helper\Data
      */
-    protected $_customerSession;
+    protected $helper;
 
     /**
-     * @param Context $context
-     * @param \Magento\Core\App\Action\FormKeyValidator $formKeyValidator
-     * @param \Magento\Customer\Model\Session $customerSession
+     * @var \Magento\Checkout\Helper\Cart
      */
-    public function __construct(
-        Context $context,
-        \Magento\Core\App\Action\FormKeyValidator $formKeyValidator,
-        \Magento\Customer\Model\Session $customerSession
-    ) {
-        $this->_formKeyValidator = $formKeyValidator;
-        $this->_customerSession = $customerSession;
-        parent::__construct($context);
-    }
+    protected $cartHelper;
 
     /**
-     * Processes localized qty (entered by user at frontend) into internal php format
-     *
-     * @param string $qty
-     * @return float|int|null
+     * @var \Magento\Framework\UrlInterface
      */
-    protected function _processLocalizedQty($qty)
-    {
-        if (!$this->_localFilter) {
-            $this->_localFilter = new \Zend_Filter_LocalizedToNormalized(
-                array('locale' => $this->_objectManager->get('Magento\Framework\Locale\ResolverInterface')->getLocaleCode())
-            );
-        }
-        $qty = $this->_localFilter->filter((double)$qty);
-        if ($qty < 0) {
-            $qty = null;
-        }
-        return $qty;
-    }
+    protected $urlBuilder;
 
     /**
-     * Retrieve current wishlist instance
-     *
-     * @return \Magento\Wishlist\Model\Wishlist|false
+     * @var \Magento\Framework\Message\ManagerInterface
      */
-    abstract protected function _getWishlist();
+    protected $messageManager;
 
     /**
-     * Add all items from wishlist to shopping cart
+     * @var \Magento\Framework\App\Response\RedirectInterface
+     */
+    protected $redirector;
+
+    /**
+     * @param Session $customerSession
+     * @param LocaleQuantityProcessor $quantityProcessor
+     * @param Cart $cart
+     * @param Logger $logger
+     * @param WishlistHelper $helper
+     * @param CartHelper $cartHelper
+     * @param UrlInterface $urlBuilder
+     * @param MessageManager $messageManager
+     * @param RedirectInterface $redirector
+     */
+    public function __construct(
+        Session $customerSession,
+        LocaleQuantityProcessor $quantityProcessor,
+        Cart $cart,
+        Logger $logger,
+        WishlistHelper $helper,
+        CartHelper $cartHelper,
+        UrlInterface $urlBuilder,
+        MessageManager $messageManager,
+        RedirectInterface $redirector
+    ) {
+        $this->customerSession = $customerSession;
+        $this->quantityProcessor = $quantityProcessor;
+        $this->cart = $cart;
+        $this->logger = $logger;
+        $this->helper = $helper;
+        $this->cartHelper = $cartHelper;
+        $this->urlBuilder = $urlBuilder;
+        $this->messageManager = $messageManager;
+        $this->redirector = $redirector;
+    }
+
+    /**
+     * Move all wishlist item to cart
      *
-     * @return void
+     * @param Wishlist $wishlist
+     * @param array $qtys
+     * @return string
      */
-    public function allcartAction()
+    public function moveAllToCart(Wishlist $wishlist, $qtys)
     {
-        $wishlist = $this->_getWishlist();
-        if (!$wishlist) {
-            $this->_forward('noroute');
-            return;
-        }
-        $isOwner = $wishlist->isOwner($this->_customerSession->getCustomerId());
+        $isOwner = $wishlist->isOwner($this->customerSession->getCustomerId());
 
         $messages = array();
         $addedItems = array();
         $notSalable = array();
         $hasOptions = array();
 
-        $cart = $this->_objectManager->get('Magento\Checkout\Model\Cart');
+        $cart = $this->cart;
         $collection = $wishlist->getItemCollection()->setVisibilityFilter();
 
-        $qtys = $this->getRequest()->getParam('qty');
         foreach ($collection as $item) {
             /** @var \Magento\Wishlist\Model\Item */
             try {
@@ -120,7 +140,7 @@ abstract class AbstractController extends \Magento\Framework\App\Action\Action
 
                 // Set qty
                 if (isset($qtys[$item->getId()])) {
-                    $qty = $this->_processLocalizedQty($qtys[$item->getId()]);
+                    $qty = $this->quantityProcessor->process($qtys[$item->getId()]);
                     if ($qty) {
                         $item->setQty($qty);
                     }
@@ -144,25 +164,20 @@ abstract class AbstractController extends \Magento\Framework\App\Action\Action
                     $cart->getQuote()->deleteItem($cartItem);
                 }
             } catch (\Exception $e) {
-                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
+                $this->logger->logException($e);
                 $messages[] = __('We cannot add this item to your shopping cart.');
             }
         }
 
         if ($isOwner) {
-            $indexUrl = $this->_objectManager->get('Magento\Wishlist\Helper\Data')->getListUrl($wishlist->getId());
+            $indexUrl = $this->helper->getListUrl($wishlist->getId());
         } else {
-            $indexUrl = $this->_objectManager->create(
-                'Magento\Framework\UrlInterface'
-            )->getUrl(
-                'wishlist/shared',
-                array('code' => $wishlist->getSharingCode())
-            );
+            $indexUrl = $this->urlBuilder->getUrl('wishlist/shared', array('code' => $wishlist->getSharingCode()));
         }
-        if ($this->_objectManager->get('Magento\Checkout\Helper\Cart')->getShouldRedirectToCart()) {
-            $redirectUrl = $this->_objectManager->get('Magento\Checkout\Helper\Cart')->getCartUrl();
-        } elseif ($this->_redirect->getRefererUrl()) {
-            $redirectUrl = $this->_redirect->getRefererUrl();
+        if ($this->cartHelper->getShouldRedirectToCart()) {
+            $redirectUrl = $this->cartHelper->getCartUrl();
+        } elseif ($this->redirector->getRefererUrl()) {
+            $redirectUrl = $this->redirector->getRefererUrl();
         } else {
             $redirectUrl = $indexUrl;
         }
@@ -226,8 +241,7 @@ abstract class AbstractController extends \Magento\Framework\App\Action\Action
             // save cart and collect totals
             $cart->save()->getQuote()->collectTotals();
         }
-        $this->_objectManager->get('Magento\Wishlist\Helper\Data')->calculate();
-
-        $this->getResponse()->setRedirect($redirectUrl);
+        $this->helper->calculate();
+        return $redirectUrl;
     }
 }
diff --git a/app/code/Magento/Tax/Service/V1/Data/SearchResultsBuilder.php b/app/code/Magento/Wishlist/Model/LocaleQuantityProcessor.php
similarity index 51%
rename from app/code/Magento/Tax/Service/V1/Data/SearchResultsBuilder.php
rename to app/code/Magento/Wishlist/Model/LocaleQuantityProcessor.php
index 15e98d8866a7e9616f545e23e3857e56735ac380..69d35a90fb003279f804e3691be06606f7252d63 100644
--- a/app/code/Magento/Tax/Service/V1/Data/SearchResultsBuilder.php
+++ b/app/code/Magento/Wishlist/Model/LocaleQuantityProcessor.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,48 +22,47 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+namespace Magento\Wishlist\Model;
 
-namespace Magento\Tax\Service\V1\Data;
-
-use Magento\Framework\Service\V1\Data\SearchCriteria;
-
-/**
- * Builder for the SearchResults Service Data Object
- *
- * @method SearchResults create()
- */
-class SearchResultsBuilder extends \Magento\Framework\Service\Data\AbstractObjectBuilder
+class LocaleQuantityProcessor
 {
     /**
-     * Set search criteria.
-     *
-     * @param SearchCriteria $searchCriteria
-     * @return SearchResultsBuilder
+     * @var \Magento\Framework\Locale\ResolverInterface
      */
-    public function setSearchCriteria(SearchCriteria $searchCriteria)
-    {
-        return $this->_set('search_criteria', $searchCriteria);
-    }
+    protected $localeResolver;
 
     /**
-     * Set total count.
-     *
-     * @param int $totalCount
-     * @return SearchResultsBuilder
+     * @var \Zend_Filter_LocalizedToNormalized
      */
-    public function setTotalCount($totalCount)
-    {
-        return $this->_set('total_count', $totalCount);
+    protected $localFilter;
+
+    /**
+     * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
+     */
+    public function __construct(
+        \Magento\Framework\Locale\ResolverInterface $localeResolver
+    ) {
+        $this->localeResolver = $localeResolver;
     }
 
     /**
-     * Set items.
+     * Process localized quantity to internal format
      *
-     * @param TaxClass[] $items
-     * @return SearchResultsBuilder
+     * @param float $qty
+     * @return array|string
      */
-    public function setItems($items)
+    public function process($qty)
     {
-        return $this->_set('items', $items);
+        if (!$this->localFilter) {
+            $this->localFilter = new \Zend_Filter_LocalizedToNormalized(
+                array('locale' => $this->localeResolver->getLocaleCode())
+            );
+        }
+        $qty = $this->localFilter->filter((double)$qty);
+        if ($qty < 0) {
+            $qty = null;
+        }
+        return $qty;
+
     }
 }
diff --git a/app/code/Magento/Wishlist/etc/di.xml b/app/code/Magento/Wishlist/etc/di.xml
index 30f0f73519ac57c88dcf4a097fa4a2134e15f3d3..91f5e8d05a1ff87d6adead2331883f1079be304c 100644
--- a/app/code/Magento/Wishlist/etc/di.xml
+++ b/app/code/Magento/Wishlist/etc/di.xml
@@ -24,6 +24,8 @@
  */
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="\Magento\Wishlist\Model\AuthenticationStateInterface" type="\Magento\Wishlist\Model\AuthenticationState" />
+    <preference for="\Magento\Wishlist\Controller\WishlistProviderInterface" type="\Magento\Wishlist\Controller\WishlistProvider" />
     <type name="Magento\Wishlist\Model\Resource\Item\Collection\Grid">
         <arguments>
             <argument name="resource" xsi:type="object">Magento\Wishlist\Model\Resource\Item</argument>
@@ -34,4 +36,7 @@
             <argument name="customerSession" xsi:type="object">Magento\Customer\Model\Session\Proxy</argument>
         </arguments>
     </type>
+    <type name="Magento\Wishlist\Controller\IndexInterface">
+        <plugin name="authentication" type="\Magento\Wishlist\Controller\Index\Plugin" sortOrder="10"/>
+    </type>
 </config>
diff --git a/dev/tests/functional/composer.json.dist b/dev/tests/functional/composer.json.dist
index 99368dbb49ebd439bd12e28cdd4da3de36f50d07..e2d1dd19e9df73f5b84a65e22fa133b1a120d035 100644
--- a/dev/tests/functional/composer.json.dist
+++ b/dev/tests/functional/composer.json.dist
@@ -1,10 +1,4 @@
 {
-    "repositories": [
-        {
-            "type": "git",
-            "url": "git://github.com/magento/mtf.git"
-        }
-    ],
     "require": {
         "magento/mtf": "dev-master",
         "php": ">=5.4.0",
diff --git a/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php b/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php
new file mode 100755
index 0000000000000000000000000000000000000000..32b2d087b110ba4794dc81178adc002b522965e7
--- /dev/null
+++ b/dev/tests/functional/lib/Mtf/Constraint/AbstractAssertForm.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Mtf\Constraint;
+
+/**
+ * Class AssertForm
+ * Abstract class AssertForm
+ */
+abstract class AbstractAssertForm extends AbstractConstraint
+{
+    /**
+     * Verify fixture and form data
+     *
+     * @param array $fixtureData
+     * @param array $formData
+     * @param bool $isStrict
+     * @param bool $isPrepareError
+     * @return array|string
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function verifyData(array $fixtureData, array $formData, $isStrict = false, $isPrepareError = true)
+    {
+        $errors = [];
+
+        foreach ($fixtureData as $key => $value) {
+            $formValue = isset($formData[$key]) ? $formData[$key] : null;
+            if (is_numeric($formValue)) {
+                $formValue = floatval($formValue);
+            }
+
+            if (null === $formValue) {
+                $errors[] = '- field "' . $key . '" is absent in form';
+            } elseif (is_array($value) && is_array($formValue)) {
+                $valueErrors = $this->verifyData($value, $formValue, true, false);
+                if (!empty($valueErrors)) {
+                    $errors[$key] = $valueErrors;
+                }
+            } elseif ($value != $formValue) {
+                if (is_array($value)) {
+                    $value = $this->arrayToString($value);
+                }
+                if (is_array($formValue)) {
+                    $formValue = $this->arrayToString($formValue);
+                }
+                $errors[] = sprintf('- %s: "%s" instead of "%s"', $key, $formValue, $value);
+            }
+        }
+
+        if ($isStrict) {
+            $diffData = array_diff(array_keys($formData), array_keys($fixtureData));
+            if ($diffData) {
+                $errors[] = '- fields ' . implode(', ', $diffData) . ' is absent in fixture';
+            }
+        }
+
+        if ($isPrepareError) {
+            return $this->prepareErrors($errors);
+        }
+        return $errors;
+    }
+
+    /**
+     * Sort multidimensional array by paths
+     *
+     * @param array $data
+     * @param array|string $paths
+     * @return array
+     */
+    protected function sortData(array $data, $paths)
+    {
+        $paths = is_array($paths) ? $paths : [$paths];
+        foreach ($paths as $path) {
+            $values = &$data;
+            $keys = explode('/', $path);
+
+            $key = array_shift($keys);
+            $order = null;
+            while (null !== $key) {
+                if (false !== strpos($key, '::')) {
+                    list($key, $order) = explode('::', $key);
+                }
+                if ($key && !isset($values[$key])) {
+                    $key = null;
+                    continue;
+                }
+
+                if ($key) {
+                    $values = &$values[$key];
+                }
+                if ($order) {
+                    $values = $this->sortMultidimensionalArray($values, $order);
+                    $order = null;
+                }
+                $key = array_shift($keys);
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Sort multidimensional array by key
+     *
+     * @param array $data
+     * @param string $key
+     * @return array
+     */
+    protected function sortMultidimensionalArray(array $data, $key)
+    {
+        $result = [];
+        foreach ($data as $value) {
+            $result[$value[$key]] = $value;
+        }
+
+        ksort($result);
+        return $result;
+    }
+
+    /**
+     * Convert array to string
+     *
+     * @param array $array
+     * @return string
+     */
+    protected function arrayToString(array $array)
+    {
+        $result = [];
+        foreach ($array as $key => $value) {
+            $value = is_array($value) ? $this->arrayToString($value) : $value;
+            $result[] = "{$key} => {$value}";
+        }
+
+        return '[' . implode(', ', $result) . ']';
+    }
+
+    /**
+     * Prepare errors to string
+     *
+     * @param array $errors
+     * @param string|null $notice
+     * @param string $indent
+     * @return string
+     */
+    protected function prepareErrors(array $errors, $notice = null, $indent = '')
+    {
+        if (empty($errors)) {
+            return '';
+        }
+
+        $result = [];
+        foreach ($errors as $key => $error) {
+            $result[] = is_array($error)
+                ? $this->prepareErrors($error, "{$indent}{$key}:\n", $indent . "\t")
+                : ($indent . $error);
+        }
+
+        if (null === $notice) {
+            $notice = "\nForm data not equals to passed from fixture:\n";
+        }
+        return $notice . implode("\n", $result);
+    }
+}
diff --git a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
index 8ba82ffa96804d9e65d629403ba46b06739ac569..b82b9673628ae62ee225afec81fefa8ae717a8fb 100644
--- a/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
+++ b/dev/tests/functional/lib/Mtf/Util/Generate/testcase.xml
@@ -35,13 +35,13 @@
     </components>
     <steps>
       <step/>
-      <step>*Steps:*</step>
-      <step> Log in as default admin user.</step>
-      <step> Go to Stores &gt; Taxes &gt; Tax Zones and Rates.</step>
-      <step> Click 'Add New Tax Rate' button.</step>
-      <step> Fill in data according to dataSet</step>
-      <step> Save Tax Rate.</step>
-      <step> Perform all assertions.</step>
+      <step>Steps:</step>
+      <step>Log in as default admin user.</step>
+      <step>Go to Stores &gt; Taxes &gt; Tax Zones and Rates.</step>
+      <step>Click 'Add New Tax Rate' button.</step>
+      <step>Fill in data according to dataSet</step>
+      <step>Save Tax Rate.</step>
+      <step>Perform all assertions.</step>
     </steps>
   </testcase>
   <testcase>
@@ -65,13 +65,13 @@
       <component>Downloadable Product (CS)</component>
     </components>
     <steps>
-    <step> Log in to Backend.</step>
-    <step> Navigate to Products &gt; Catalog.</step>
-    <step> Start to create new Downloadable product.</step>
-    <step> Fill in data according to data set.</step>
-    <step> Fill Downloadable Information tab according to data set.</step>
-    <step> Save product.</step>
-    <step> Verify created product.</step>
+    <step>Log in to Backend.</step>
+    <step>Navigate to Products &gt; Catalog.</step>
+    <step>Start to create new Downloadable product.</step>
+    <step>Fill in data according to data set.</step>
+    <step>Fill Downloadable Information tab according to data set.</step>
+    <step>Save product.</step>
+    <step>Verify created product.</step>
     </steps>
   </testcase>
   <testcase>
@@ -85,7 +85,7 @@
     </components>
     <steps>
       <step/>
-      <step>*Preconditions:*</step>
+      <step>Preconditions:</step>
       <step> Two specific simple product is created(unique sku,name,short/full description, tax class)</step>
       <step/>
       <step>Steps</step>
@@ -96,4 +96,21 @@
       <step>Perform all asserts</step>
     </steps>
   </testcase>
+  <testcase>
+    <id>MTA-129</id>
+    <ticketId>MTA-129</ticketId>
+    <name>SearchEntityResultsTest</name>
+    <description>Test Creation for SearchEntity results</description>
+    <module>Search</module>
+    <components>
+      <component>Search Frontend (MX)</component>
+    </components>
+      <step>Preconditions:</step>
+      <step>1. All product types are created.</step>
+      <step/>
+      <step>Steps:</step>
+      <step>1. Navigate to frontend on index page.</step>
+      <step>2. Input test data into "search field" and press Enter key.</step>
+      <step>3. Perform all assertions.</step>
+  </testcase>
 </testcases>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Menu.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Menu.php
index eae53e60d1a375967270a403439a1fbface76a8e..2fbeea1e1a30772dc4e8d43367b07c9a54fce0b0 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Menu.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Menu.php
@@ -33,25 +33,6 @@ use Mtf\Client\Element\Locator;
  */
 class Menu extends Block
 {
-    /**
-     * Top Elements of menu
-     *
-     * @var string
-     */
-    protected $navigationMenuItems = "/li";
-
-    /**
-     * Check menu items count
-     *
-     * @param int $number
-     * @return bool
-     */
-    public function assertNavigationMenuItemsCount($number)
-    {
-        $selector = $this->navigationMenuItems . '[' . ($number + 1) . ']';
-        return !$this->_rootElement->find($selector, Locator::SELECTOR_XPATH)->isVisible();
-    }
-
     /**
      * Returns array of parent menu items present on dashboard menu
      *
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..5fac650526ed5cf7ccb87df47a0e3c09e2d00b94
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Block\System\Variable\Edit;
+
+use Mtf\Block\Form;
+
+/**
+ * Class Form
+ * Form for custom system variable creation
+ */
+class VariableForm extends Form
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c103192abb9d3556bbfdb2fcc4f71d14d34f78f0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Edit/VariableForm.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <wrapper>variable</wrapper>
+    <fields>
+        <code />
+        <name />
+        <html_value />
+        <plain_value />
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Grid.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..efec17de4dcaf326c648640362fccf699ee06327
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/System/Variable/Grid.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Backend\Test\Block\System\Variable;
+
+use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid;
+
+/**
+ * Class Grid
+ * System Variable management grid
+ */
+class Grid extends AbstractGrid
+{
+    /**
+     * Locator value for link in action column
+     *
+     * @var string
+     */
+    protected $editLink = 'td[class*=col-code]';
+
+    /**
+     * Initialize block elements
+     *
+     * @var array
+     */
+    protected $filters = [
+        'code' => [
+            'selector' => 'input[name="code"]',
+        ],
+        'name' => [
+            'selector' => 'input[name="name"]',
+        ],
+    ];
+}
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
index 3d78145b1fc14276478d7fd9a84d0a5c415c8274..52532f5e3336b8223c40b477119c961b0111fcac 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Block/Widget/FormTabs.php
@@ -305,7 +305,7 @@ class FormTabs extends Form
      * @return Tab
      * @throws \Exception
      */
-    protected function getTabElement($tabName)
+    public function getTabElement($tabName)
     {
         $tabClass = $this->tabs[$tabName]['class'];
         /** @var Tab $tabElement */
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Conditions.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Conditions.php
index fa0096e185d41b363257a90d9f23366e71a11fe9..bc1651bbea52e383ac035b82062bed0fe1072efd 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Conditions.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Conditions.php
@@ -118,8 +118,10 @@ abstract class Conditions extends Curl
      */
     protected function prepareCondition($conditions)
     {
-        $conditions = $this->decodeValue("{Conditions combination:[{$conditions}]}");
-        return $this->convertMultipleCondition($conditions);
+        $decodeConditions = empty($conditions)
+            ? $this->decodeValue("[Conditions combination]")
+            : $this->decodeValue("{Conditions combination:[{$conditions}]}");
+        return $this->convertMultipleCondition($decodeConditions);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
old mode 100644
new mode 100755
index 9ccc06a5de2fd8120caed05d12863e4cfbdc7115..1b6706c7c51af8d71574963c96ef995cb480cc9e
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Handler/Extractor.php
@@ -50,17 +50,26 @@ class Extractor
      */
     protected $url;
 
+    /**
+     * Flag is search all match
+     *
+     * @var bool
+     */
+    protected $isAll;
+
     /**
      * Setting all Pagination params for Pagination object.
      * Required url for cURL request and regexp pattern for searching in cURL response.
      *
      * @param string $url
      * @param string $regExpPattern
+     * @param bool $isAll
      */
-    public function __construct($url, $regExpPattern)
+    public function __construct($url, $regExpPattern, $isAll = false)
     {
         $this->url = $url;
         $this->regExpPattern = $regExpPattern;
+        $this->isAll = $isAll;
     }
 
     /**
@@ -77,9 +86,14 @@ class Extractor
         $curl->write(CurlInterface::POST, $url, '1.0');
         $response = $curl->read();
         $curl->close();
-        preg_match($this->regExpPattern, $response, $matches);
+        if ($this->isAll) {
+            preg_match_all($this->regExpPattern, $response, $matches);
+        } else {
+            preg_match($this->regExpPattern, $response, $matches);
+        }
 
-        if (count($matches) == 0) {
+        $countMatches = $this->isAll ? count($matches[1]) : count($matches);
+        if ($countMatches == 0) {
             throw new \Exception('Matches array can\'t be empty.');
         }
         return $matches;
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.php b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.php
index 82c4ff5f278b28ac1af25d2741d2961002ed8ddd..6ca6f02583bc8e06ff427ed465ca97cb0c019b2a 100644
--- a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.php
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.php
@@ -24,50 +24,39 @@
 
 namespace Magento\Backend\Test\Page;
 
-use Mtf\Factory\Factory;
-use Mtf\Page\Page;
-use Mtf\Client\Element\Locator;
+use Mtf\Page\BackendPage;
 
 /**
  * Class Dashboard
  * Dashboard (Home) page for backend
- *
  */
-class Dashboard extends Page
+class Dashboard extends BackendPage
 {
     /**
      * URL part for backend authorization
      */
     const MCA = 'admin/dashboard';
 
-    /**
-     * Header panel block of dashboard page
-     *
-     * @var string
-     */
-    protected $adminPanelHeader = 'page-header';
-
-    /**
-     * Page title block
-     *
-     * @var string
-     */
-    protected $titleBlock = '.page-title';
-
-    /**
-     * Top menu selector
-     *
-     * @var string
-     */
-    protected $menuBlock = '.navigation';
-
-    /**
-     * Constructor
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
+    protected $_blocks = [
+        'adminPanelHeader' => [
+            'name' => 'adminPanelHeader',
+            'class' => 'Magento\Backend\Test\Block\Page\Header',
+            'locator' => '.page-header',
+            'strategy' => 'css selector',
+        ],
+        'titleBlock' => [
+            'name' => 'titleBlock',
+            'class' => 'Magento\Theme\Test\Block\Html\Title',
+            'locator' => '.page-title',
+            'strategy' => 'css selector',
+        ],
+        'menuBlock' => [
+            'name' => 'menuBlock',
+            'class' => 'Magento\Backend\Test\Block\Menu',
+            'locator' => '.navigation',
+            'strategy' => 'css selector',
+        ],
+    ];
 
     /**
      * Get admin panel header block instance
@@ -76,9 +65,7 @@ class Dashboard extends Page
      */
     public function getAdminPanelHeader()
     {
-        return Factory::getBlockFactory()->getMagentoBackendPageHeader(
-            $this->_browser->find($this->adminPanelHeader, Locator::SELECTOR_CLASS_NAME)
-        );
+        return $this->getBlockInstance('adminPanelHeader');
     }
 
     /**
@@ -88,9 +75,7 @@ class Dashboard extends Page
      */
     public function getTitleBlock()
     {
-        return Factory::getBlockFactory()->getMagentoThemeHtmlTitle(
-            $this->_browser->find($this->titleBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('titleBlock');
     }
 
     /**
@@ -100,8 +85,6 @@ class Dashboard extends Page
      */
     public function getMenuBlock()
     {
-        return Factory::getBlockFactory()->getMagentoBackendMenu(
-            $this->_browser->find($this->menuBlock, Locator::SELECTOR_CSS)
-        );
+        return $this->getBlockInstance('menuBlock');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.xml b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.xml
new file mode 100644
index 0000000000000000000000000000000000000000..848d6e7be06c30045438c95bdb00bdd5ad709f86
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Backend/Test/Page/Dashboard.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="admin/dashboard">
+    <block>
+        <name>adminPanelHeader</name>
+        <class>Magento\Backend\Test\Block\Page\Header</class>
+        <locator>.page-header</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>titleBlock</name>
+        <class>Magento\Theme\Test\Block\Html\Title</class>
+        <locator>.page-title</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>menuBlock</name>
+        <class>Magento\Backend\Test\Block\Menu</class>
+        <locator>.navigation</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
index 647546e12bb6752421ad7ccf964abf15838329ec..bcaf9cbb617912ecbf37f97d7c9788a719112219 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle.php
@@ -74,7 +74,7 @@ class Bundle extends Tab
         if (!isset($fields['bundle_selections'])) {
             return $this;
         }
-        $bundleOptions = $this->prepareBundleOptions($fields['bundle_selections']['value']);
+        $bundleOptions = $this->prepareBundleOptions($fields['bundle_selections']['value']['bundle_options']);
         $blocksNumber = 0;
         foreach ($bundleOptions as $bundleOption) {
             $this->_rootElement->find($this->addNewOption)->click();
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
index e7305ce2070e525ef0f549284ac39c36ba72220a..5aacc6f8d6f65bf14016c57848d81fab696b7926 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option.php
@@ -167,9 +167,9 @@ class Option extends Block
      */
     private function fillOptionData(array $fields)
     {
-        $this->_rootElement->find($this->title)->setValue($fields['title']['value']);
-        $this->_rootElement->find($this->type, Locator::SELECTOR_CSS, 'select')->setValue($fields['type']['value']);
+        $this->_rootElement->find($this->title)->setValue($fields['title']);
+        $this->_rootElement->find($this->type, Locator::SELECTOR_CSS, 'select')->setValue($fields['type']);
         $this->_rootElement->find($this->required, Locator::SELECTOR_CSS, 'checkbox')
-            ->setValue($fields['required']['value']);
+            ->setValue($fields['required']);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
index ac609c0ade5e4baec0ab6746da71db2d8ec2e51b..fff6f222d75d7e9bbf1200b60834825a891ba827 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Block/Adminhtml/Catalog/Product/Edit/Tab/Bundle/Option/Selection.php
@@ -47,11 +47,23 @@ class Selection extends Block
      */
     protected function _init()
     {
-        $this->mapping = array(
-            'selection_price_value' => "[name$='[selection_price_value]']",
-            'selection_price_type' => "[name$='[selection_price_type]']",
-            'selection_qty' => "[name$='[selection_qty]']"
-        );
+        $this->mapping = [
+            'selection_price_value' => [
+                'selector' => "[name$='[selection_price_value]']",
+                'type' => 'input',
+
+            ],
+            'selection_price_type' => [
+                'selector' => "[name$='[selection_price_type]']",
+                'type' => 'select',
+
+            ],
+            'selection_qty' => [
+                'selector' => "[name$='[selection_qty]']",
+                'type' => 'input',
+
+            ],
+        ];
     }
 
     /**
@@ -61,11 +73,13 @@ class Selection extends Block
      */
     public function fillProductRow(array $fields)
     {
-        foreach ($fields as $key => $field) {
+        foreach ($fields as $key => $value) {
             if (isset($this->mapping[$key])) {
-                $typifiedElement = isset($field['input']) ? $field['input'] : null;
-                $this->_rootElement->find($this->mapping[$key], Locator::SELECTOR_CSS, $typifiedElement)
-                    ->setValue($field['value']);
+                $this->_rootElement->find(
+                    $this->mapping[$key]['selector'],
+                    Locator::SELECTOR_CSS,
+                    $this->mapping[$key]['type']
+                )->setValue($value);
             }
         }
     }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php
index 536093cdb381cf19a45d2d0815e143e686627a16..c2633656f9f80249a60a691f378437aa83a043ba 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle.php
@@ -30,7 +30,6 @@ use Magento\Catalog\Test\Fixture\Product;
 
 /**
  * Class Bundle
- *
  */
 class Bundle extends Product
 {
@@ -88,10 +87,10 @@ class Bundle extends Product
     {
         $options = array();
         $bundleOptions = $this->getData('fields/bundle_selections/value');
-        foreach ($bundleOptions as $optionData) {
-            $optionName = $optionData['title']['value'];
+        foreach ($bundleOptions['bundle_options'] as $optionData) {
+            $optionName = $optionData['title'];
             foreach ($optionData['assigned_products'] as $productData) {
-                $options[$optionName] = $productData['search_data']['name'];
+                $options[$optionName][] = $productData['search_data']['name'];
             }
         }
         return $options;
@@ -115,19 +114,23 @@ class Bundle extends Product
      */
     public function getSelectionData()
     {
+        $typeMapping = [
+            'Drop-down' => 'select'
+        ];
         $options = $this->getData('checkout/selection');
-        $selectionData = array();
+        $selectionData = [];
         foreach ($options as $option => $selection) {
-            $selectionItem['type'] = $this->getData('fields/bundle_selections/value/' . $option . '/type/input_value');
+            $fieldPrefix = 'fields/bundle_selections/value/bundle_options/';
+            $selectionItem['type'] = $typeMapping[$this->getData($fieldPrefix . $option . '/type')];
             $selectionItem['qty'] = $this->getData(
-                'fields/bundle_selections/value/' . $option .
-                '/assigned_products/' . $selection . '/data/selection_qty/value'
+                $fieldPrefix . $option . '/assigned_products/' . $selection . '/data/selection_qty'
             );
             $selectionItem['value'] = $this->getData(
-                'fields/bundle_selections/value/' . $option . '/assigned_products/' . $selection . '/search_data/name'
+                $fieldPrefix . $option . '/assigned_products/' . $selection . '/search_data/name'
             );
             $selectionData[] = $selectionItem;
         }
+
         return $selectionData;
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Selections.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Selections.php
deleted file mode 100644
index 0bb0afe523ea4321cf17150974de45dfa78d1f65..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Selections.php
+++ /dev/null
@@ -1,269 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Bundle\Test\Fixture\Bundle;
-
-use Mtf\Fixture\FixtureFactory;
-use Mtf\Fixture\FixtureInterface;
-
-/**
- * Class Bundle
- *
- * Data keys:
- *  - preset (bundle options preset name)
- *  - products (comma separated sku identifiers)
- *
- */
-class Selections implements FixtureInterface
-{
-    /**
-     * @var \Mtf\Fixture\FixtureFactory
-     */
-    protected $fixtureFactory;
-
-    /**
-     * @var string
-     */
-    protected $currentPreset;
-
-    /**
-     * @constructor
-     * @param FixtureFactory $fixtureFactory
-     * @param $data
-     * @param array $params
-     * @param bool $persist
-     */
-    public function __construct(
-        FixtureFactory $fixtureFactory,
-        $data,
-        array $params = [],
-        $persist = false
-    ) {
-        $this->fixtureFactory = $fixtureFactory;
-
-        $this->data = $data;
-
-        if (isset($this->data['products'])) {
-            $products = explode(',', $this->data['products']);
-            $this->data['products'] = [];
-            foreach ($products as $key => $product) {
-                list($fixture, $dataSet) = explode('::', $product);
-                $this->data['products'][$key] = $this->fixtureFactory
-                    ->createByCode($fixture, ['dataSet' => $dataSet]);
-            }
-        }
-        $this->currentPreset = $this->data['preset'];
-        $this->data['preset'] = $this->getPreset($this->data['preset']);
-
-        $this->params = $params;
-        if ($persist) {
-            $this->persist();
-        }
-    }
-
-    /**
-     * Persist bundle selections products
-     *
-     * @return void
-     */
-    public function persist()
-    {
-        if (isset($this->data['products'])) {
-            foreach ($this->data['products'] as $product) {
-                /** @var $product FixtureInterface */
-                $product->persist();
-            }
-        }
-    }
-
-    /**
-     * Return prepared data set
-     *
-     * @param $key [optional]
-     * @return mixed
-     *
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function getData($key = null)
-    {
-        return $this->data;
-    }
-
-    /**
-     * Return data set configuration settings
-     *
-     * @return string
-     */
-    public function getDataConfig()
-    {
-        return $this->params;
-    }
-
-    /**
-     * Get selection for performing checkout
-     *
-     * @return array|null
-     */
-    public function getSelectionForCheckout()
-    {
-        /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple $product */
-        $product = $this->data['products'][0];
-        $selectionsForCheckout = [
-            'default' => [
-                0 => [
-                    'value' => $product->getName(),
-                    'type' => 'select',
-                    'qty' => 1
-                ]
-            ],
-            'second' => [
-                0 => [
-                    'value' => $product->getName(),
-                    'type' => 'select',
-                    'qty' => 1
-                ]
-            ],
-        ];
-        if (!isset($selectionsForCheckout[$this->currentPreset])) {
-            return null;
-        }
-        return $selectionsForCheckout[$this->currentPreset];
-    }
-
-    /**
-     * @param $name
-     * @return mixed
-     * @throws \InvalidArgumentException
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    protected function getPreset($name)
-    {
-        $presets = [
-            'default' => [
-                'name' => 'Bundle Selections Default Preset',
-                'items' => [
-                    'bundle_item_0' => [
-                        'title' => [
-                            'value' => 'Drop-down Option'
-                        ],
-                        'type' => [
-                            'value' => 'Drop-down',
-                            'input_value' => 'select'
-                        ],
-                        'required' => [
-                            'value' => 'Yes',
-                            'input_value' => '1'
-                        ],
-                        'assigned_products' => [
-                            0 => [
-                                'search_data' => [
-                                    'name' => '%item1::getName%',
-                                ],
-                                'data' => [
-                                    'selection_qty' => [
-                                        'value' => 1
-                                    ],
-                                    'product_id' => [
-                                        'value' => '%item1::getProductId%'
-                                    ]
-                                ]
-                            ],
-                            1 => [
-                                'search_data' => [
-                                    'name' => '%item2::getName%',
-                                ],
-                                'data' => [
-                                    'selection_qty' => [
-                                        'value' => 1
-                                    ],
-                                    'product_id' => [
-                                        'value' => '%item2::getProductId%'
-                                    ]
-                                ]
-                            ]
-                        ]
-                    ]
-                ]
-            ],
-            'second' => [
-                'name' => 'Bundle Selections Default Preset',
-                'items' => [
-                    'bundle_item_0' => [
-                        'title' => [
-                            'value' => 'Drop-down Second Option'
-                        ],
-                        'type' => [
-                            'value' => 'Drop-down',
-                            'input_value' => 'select'
-                        ],
-                        'required' => [
-                            'value' => 'Yes',
-                            'input_value' => '1'
-                        ],
-                        'assigned_products' => [
-                            0 => [
-                                'search_data' => [
-                                    'name' => '%item1::getName%',
-                                ],
-                                'data' => [
-                                    'selection_qty' => [
-                                        'value' => 1
-                                    ],
-                                    'product_id' => [
-                                        'value' => '%item1::getProductId%'
-                                    ],
-                                    'selection_price_value' => [
-                                        'value' => '5'
-                                    ]
-                                ]
-                            ],
-                            1 => [
-                                'search_data' => [
-                                    'name' => '%item2::getName%',
-                                ],
-                                'data' => [
-                                    'selection_qty' => [
-                                        'value' => 1
-                                    ],
-                                    'product_id' => [
-                                        'value' => '%item2::getProductId%'
-                                    ],
-                                    'selection_price_value' => [
-                                        'value' => '10'
-                                    ]
-                                ]
-                            ]
-                        ]
-                    ]
-                ]
-            ]
-        ];
-        if (!isset($presets[$name])) {
-            throw new \InvalidArgumentException(
-                sprintf('Wrong Bundle Selections preset name: %s', $name)
-            );
-        }
-        return $presets[$name];
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php
index 8d6d0772a4728687ab92c012fe481d3c70c9324c..9e05a48b88dd6334f898ff9959e821f9d0204f85 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleDynamic.php
@@ -28,7 +28,6 @@ use Mtf\Factory\Factory;
 
 /**
  * Class BundleDynamic
- *
  */
 class BundleDynamic extends Bundle
 {
@@ -83,42 +82,28 @@ class BundleDynamic extends Bundle
                 ),
                 'bundle_selections' => array(
                     'value' => array(
-                        'bundle_item_0' => array(
-                            'title' => array(
-                                'value' => 'Drop-down Option'
-                            ),
-                            'type' => array(
-                                'value' => 'Drop-down',
-                                'input_value' => 'select'
-                            ),
-                            'required' => array(
-                                'value' => 'Yes',
-                                'input_value' => '1'
-                            ),
-                            'assigned_products' => array(
-                                'assigned_product_0' => array(
-                                    'search_data' => array(
-                                        'name' => '%item1_simple1::getName%',
-                                    ),
-                                    'data' => array(
-                                        'selection_qty' => array(
-                                            'value' => 1
+                        'bundle_options' => array(
+                            'bundle_item_0' => array(
+                                'title' => 'Drop-down Option',
+                                'type' => 'Drop-down',
+                                'required' => 'Yes',
+                                'assigned_products' => array(
+                                    'assigned_product_0' => array(
+                                        'search_data' => array(
+                                            'name' => '%item1_simple1::getName%',
                                         ),
-                                        'product_id' => array(
-                                            'value' => '%item1_simple1::getProductId%'
+                                        'data' => array(
+                                            'selection_qty' => 1,
+                                            'product_id' => '%item1_simple1::getProductId%'
                                         )
-                                    )
-                                ),
-                                'assigned_product_1' => array(
-                                    'search_data' => array(
-                                        'name' => '%item1_virtual2::getName%',
                                     ),
-                                    'data' => array(
-                                        'selection_qty' => array(
-                                            'value' => 1
+                                    'assigned_product_1' => array(
+                                        'search_data' => array(
+                                            'name' => '%item1_virtual2::getName%',
                                         ),
-                                        'product_id' => array(
-                                            'value' => '%item1_virtual2::getProductId%'
+                                        'data' => array(
+                                            'selection_qty' => 1,
+                                            'product_id' => '%item1_virtual2::getProductId%'
                                         )
                                     )
                                 )
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php
index 41f9c2001a7ad8657d2f1ceea67051596073b929..7ec001adb6b9f1efca08d23a3e0d93462e79e96c 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/BundleFixed.php
@@ -28,7 +28,6 @@ use Mtf\Factory\Factory;
 
 /**
  * Class BundleFixed
- *
  */
 class BundleFixed extends Bundle
 {
@@ -99,58 +98,32 @@ class BundleFixed extends Bundle
                 ),
                 'bundle_selections' => array(
                     'value' => array(
-                        'bundle_item_0' => array(
-                            'title' => array(
-                                'value' => 'Drop-down Option'
-                            ),
-                            'type' => array(
-                                'value' => 'Drop-down',
-                                'input_value' => 'select'
-                            ),
-                            'required' => array(
-                                'value' => 'Yes',
-                                'input_value' => '1'
-                            ),
-                            'assigned_products' => array(
-                                'assigned_product_0' => array(
-                                    'search_data' => array(
-                                        'name' => '%item1_simple1::getName%',
-                                    ),
-                                    'data' => array(
-                                        'selection_price_value' => array(
-                                            'value' => 10
-                                        ),
-                                        'selection_price_type' => array(
-                                            'value' => 'Fixed',
-                                            'input' => 'select',
-                                            'input_value' => 0
-                                        ),
-                                        'selection_qty' => array(
-                                            'value' => 1
+                        'bundle_options' => array(
+                            'bundle_item_0' => array(
+                                'title' => 'Drop-down Option',
+                                'type' => 'Drop-down',
+                                'required' => 'Yes',
+                                'assigned_products' => array(
+                                    'assigned_product_0' => array(
+                                        'search_data' => array(
+                                            'name' => '%item1_simple1::getName%',
                                         ),
-                                        'product_id' => array(
-                                            'value' => '%item1_simple1::getProductId%'
+                                        'data' => array(
+                                            'selection_price_value' => 10,
+                                            'selection_price_type' => 'Fixed',
+                                            'selection_qty' => 1,
+                                            'product_id' => '%item1_simple1::getProductId%'
                                         )
-                                    )
-                                ),
-                                'assigned_product_1' => array(
-                                    'search_data' => array(
-                                        'name' => '%item1_virtual2::getName%',
                                     ),
-                                    'data' => array(
-                                        'selection_price_value' => array(
-                                            'value' => 20
-                                        ),
-                                        'selection_price_type' => array(
-                                            'value' => 'Percent',
-                                            'input' => 'select',
-                                            'input_value' => 1
-                                        ),
-                                        'selection_qty' => array(
-                                            'value' => 1
+                                    'assigned_product_1' => array(
+                                        'search_data' => array(
+                                            'name' => '%item1_virtual2::getName%',
                                         ),
-                                        'product_id' => array(
-                                            'value' => '%item1_virtual2::getProductId%'
+                                        'data' => array(
+                                            'selection_price_value' => 20,
+                                            'selection_price_type' => 'Percent',
+                                            'selection_qty' => 1,
+                                            'product_id' => '%item1_virtual2::getProductId%'
                                         )
                                     )
                                 )
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
index 3419fa0d58417fe98ebad941b54cd3635f957257..bf03465b8c63fe7da2414982572ac0d779538907 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.php
@@ -33,9 +33,10 @@ use Mtf\System\Event\EventManagerInterface;
 
 /**
  * Class CatalogProductBundle
+ * Fixture for Bundle product
  *
  * @SuppressWarnings(PHPMD.ExcessivePublicCount)
- * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.TooManyFields) 
  */
 class CatalogProductBundle extends InjectableFixture
 {
@@ -96,14 +97,10 @@ class CatalogProductBundle extends InjectableFixture
     ];
 
     protected $defaultDataSet = [
-        'enable_googlecheckout' => null,
-        'msrp_display_actual_price_type' => null,
-        'msrp_enabled' => null,
-        'options_container' => null,
-        'quantity_and_stock_status' => null,
-        'status' => null,
-        'tax_class_id' => null,
-        'visibility' => null,
+        'name' => 'BundleProduct %isolation%',
+        'sku_type' => 'Dynamic',
+        'price_type' => 'Dynamic',
+        'weight_type' => 'Dynamic',
     ];
 
     protected $category_ids = [
@@ -112,6 +109,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'text',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds',
     ];
 
     protected $country_of_manufacture = [
@@ -168,6 +166,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'textarea',
+        'group' => 'product-details'
     ];
 
     protected $enable_googlecheckout = [
@@ -192,6 +191,16 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'select',
+        'group' => 'autosettings'
+    ];
+
+    protected $use_config_gift_message_available = [
+        'attribute_code' => 'use_config_gift_message_available',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'checkbox',
+        'group' => 'autosettings'
     ];
 
     protected $group_price = [
@@ -347,8 +356,26 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '1',
         'default_value' => '',
         'input' => 'price',
-        'group' => 'product-details',
-        'source' => 'Magento\Bundle\Test\Fixture\Bundle\Price'
+        'source' => 'Magento\Bundle\Test\Fixture\CatalogProductBundle\Price',
+        'group' => 'product-details'
+    ];
+
+    protected $price_from = [
+        'attribute_code' => 'price_from',
+        'backend_type' => 'decimal',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'price',
+        'group' => 'product-details'
+    ];
+
+    protected $price_to = [
+        'attribute_code' => 'price_to',
+        'backend_type' => 'decimal',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'price',
+        'group' => 'product-details'
     ];
 
     protected $price_type = [
@@ -360,12 +387,22 @@ class CatalogProductBundle extends InjectableFixture
         'group' => 'product-details',
     ];
 
+    protected $status = [
+        'attribute_code' => 'status',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'checkbox',
+        'group' => 'product-details'
+    ];
+
     protected $price_view = [
         'attribute_code' => 'price_view',
         'backend_type' => 'int',
         'is_required' => '1',
         'default_value' => '',
         'input' => 'select',
+        'group' => 'advanced-pricing'
     ];
 
     protected $quantity_and_stock_status = [
@@ -374,6 +411,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '1',
         'input' => 'select',
+        'group' => 'product-details'
     ];
 
     protected $required_options = [
@@ -384,12 +422,25 @@ class CatalogProductBundle extends InjectableFixture
         'input' => 'text',
     ];
 
+    protected $use_config_manage_stock = [
+        'attribute_code' => 'use_config_manage_stock',
+        'input' => 'checkbox',
+        'group' => 'advanced-inventory'
+    ];
+
+    protected $manage_stock = [
+        'attribute_code' => 'manage_stock',
+        'input' => 'select',
+        'group' => 'advanced-inventory',
+    ];
+
     protected $shipment_type = [
         'attribute_code' => 'shipment_type',
         'backend_type' => 'int',
         'is_required' => '1',
         'default_value' => '',
-        'input' => '',
+        'input' => 'select',
+        'group' => 'product-details'
     ];
 
     protected $short_description = [
@@ -398,6 +449,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'textarea',
+        'group' => 'autosettings'
     ];
 
     protected $sku = [
@@ -415,9 +467,27 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '1',
         'default_value' => '',
         'input' => 'select',
+        'group' => 'product-details'
+    ];
+
+    protected $weight_type = [
+        'attribute_code' => 'weight_type',
+        'backend_type' => 'int',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'select',
         'group' => 'product-details',
     ];
 
+    protected $weight = [
+        'attribute_code' => 'weight',
+        'backend_type' => 'decimal',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'product-details'
+    ];
+
     protected $small_image = [
         'attribute_code' => 'small_image',
         'backend_type' => 'varchar',
@@ -434,45 +504,42 @@ class CatalogProductBundle extends InjectableFixture
         'input' => 'text',
     ];
 
-    protected $special_from_date = [
-        'attribute_code' => 'special_from_date',
-        'backend_type' => 'datetime',
-        'is_required' => '0',
-        'default_value' => '',
-        'input' => 'date',
-    ];
-
     protected $special_price = [
         'attribute_code' => 'special_price',
         'backend_type' => 'decimal',
         'is_required' => '0',
         'default_value' => '',
         'input' => 'price',
-        'group' => 'advanced-pricing'
+        'group' => 'advanced-pricing',
     ];
 
-    protected $special_to_date = [
-        'attribute_code' => 'special_to_date',
-        'backend_type' => 'datetime',
+    protected $special_from_date = [
+        'attribute_code' => 'special_from_date',
+        'backend_type' => 'data',
         'is_required' => '0',
         'default_value' => '',
-        'input' => 'date',
+        'input' => 'price',
+        'group' => 'advanced-pricing',
+        'source' => 'Magento\Backend\Test\Fixture\Date',
     ];
 
-    protected $status = [
-        'attribute_code' => 'status',
-        'backend_type' => 'int',
+    protected $special_to_date = [
+        'attribute_code' => 'special_to_date',
+        'backend_type' => 'data',
         'is_required' => '0',
-        'default_value' => '1',
-        'input' => 'select',
+        'default_value' => '',
+        'input' => 'price',
+        'group' => 'advanced-pricing',
+        'source' => 'Magento\Backend\Test\Fixture\Date',
     ];
 
     protected $tax_class_id = [
         'attribute_code' => 'tax_class_id',
         'backend_type' => 'int',
         'is_required' => '0',
-        'default_value' => '2',
+        'default_value' => 'Taxable Goods',
         'input' => 'select',
+        'group' => 'product-details',
         'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TaxClass',
     ];
 
@@ -498,6 +565,8 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'text',
+        'group' => 'advanced-pricing',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\TierPriceOptions'
     ];
 
     protected $updated_at = [
@@ -514,6 +583,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'text',
+        'group' => 'autosettings'
     ];
 
     protected $url_path = [
@@ -530,22 +600,7 @@ class CatalogProductBundle extends InjectableFixture
         'is_required' => '0',
         'default_value' => '4',
         'input' => 'select',
-    ];
-
-    protected $weight = [
-        'attribute_code' => 'weight',
-        'backend_type' => 'decimal',
-        'is_required' => '0',
-        'default_value' => '',
-        'input' => 'weight',
-    ];
-
-    protected $weight_type = [
-        'attribute_code' => 'weight_type',
-        'backend_type' => 'int',
-        'is_required' => '1',
-        'default_value' => '',
-        'input' => '',
+        'group' => 'autosettings',
     ];
 
     protected $id = [
@@ -558,7 +613,7 @@ class CatalogProductBundle extends InjectableFixture
         'backend_type' => 'virtual',
         'is_required' => '1',
         'group' => 'bundle',
-        'source' => 'Magento\Bundle\Test\Fixture\Bundle\Selections',
+        'source' => 'Magento\Bundle\Test\Fixture\CatalogProductBundle\BundleSelections',
     ];
 
     protected $custom_options = [
@@ -569,6 +624,26 @@ class CatalogProductBundle extends InjectableFixture
         'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
+    protected $new_variations_attribute_set_id = [
+        'attribute_code' => 'new_variations_attribute_set_id'
+    ];
+
+    protected $affect_bundle_product_selection = [
+        'attribute_code' => 'affect_bundle_product_selection'
+    ];
+
+    protected $stock_data = [
+        'attribute_code' => 'stock_data'
+    ];
+
+    protected $category_id = [
+        'attribute_code' => 'category_id'
+    ];
+
+    protected $website_ids = [
+        'attribute_code' => 'website_ids'
+    ];
+
     public function getCategoryIds()
     {
         return $this->getData('category_ids');
@@ -719,6 +794,16 @@ class CatalogProductBundle extends InjectableFixture
         return $this->getData('price');
     }
 
+    public function getPriceFrom()
+    {
+        return $this->getData('price_from');
+    }
+
+    public function getPriceTo()
+    {
+        return $this->getData('price_to');
+    }
+
     public function getPriceType()
     {
         return $this->getData('price_type');
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml
index 8872053561f2dff7ebde5a7fa645c53d4eaf83bf..21874f301c9e4fd06e7e01a5dda024559cb1cd0b 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle.xml
@@ -115,7 +115,7 @@
             <default_value></default_value>
             <input>text</input>
             <group>advanced-pricing</group>
-            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions</fixture>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions</source>
         </group_price>
         <has_options>
             <attribute_code>has_options</attribute_code>
@@ -242,7 +242,7 @@
             <is_required>1</is_required>
             <default_value></default_value>
             <input>price</input>
-            <fixture>Magento\Bundle\Test\Fixture\Bundle\Price</fixture>
+            <source>Magento\Bundle\Test\Fixture\CatalogProductBundle\Price</source>
         </price>
         <price_type>
             <attribute_code>price_type</attribute_code>
@@ -314,13 +314,6 @@
             <default_value></default_value>
             <input>text</input>
         </small_image_label>
-        <special_from_date>
-            <attribute_code>special_from_date</attribute_code>
-            <backend_type>datetime</backend_type>
-            <is_required>0</is_required>
-            <default_value></default_value>
-            <input>date</input>
-        </special_from_date>
         <special_price>
             <attribute_code>special_price</attribute_code>
             <backend_type>decimal</backend_type>
@@ -329,26 +322,40 @@
             <input>price</input>
             <group>advanced-pricing</group>
         </special_price>
+        <special_from_date>
+            <attribute_code>special_from_date</attribute_code>
+            <backend_type>decimal</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>price</input>
+            <group>advanced-pricing</group>
+            <source>Magento\Backend\Test\Fixture\Date</source>
+        </special_from_date>
         <special_to_date>
             <attribute_code>special_to_date</attribute_code>
-            <backend_type>datetime</backend_type>
+            <backend_type>decimal</backend_type>
             <is_required>0</is_required>
             <default_value></default_value>
-            <input>date</input>
+            <input>price</input>
+            <group>advanced-pricing</group>
+            <source>Magento\Backend\Test\Fixture\Date</source>
         </special_to_date>
         <status>
             <attribute_code>status</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>1</default_value>
-            <input>select</input>
+            <default_value>Product online</default_value>
+            <input>checkbox</input>
+            <group>product-details</group>
         </status>
         <tax_class_id>
             <attribute_code>tax_class_id</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>2</default_value>
+            <default_value>Taxable Goods</default_value>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\TaxClass</source>
             <input>select</input>
+            <group>product-details</group>
         </tax_class_id>
         <thumbnail>
             <attribute_code>thumbnail</attribute_code>
@@ -422,14 +429,14 @@
             <backend_type>virtual</backend_type>
             <is_required>1</is_required>
             <group>bundle</group>
-            <fixture>Magento\Bundle\Test\Fixture\Bundle\Selections</fixture>
+            <source>Magento\Bundle\Test\Fixture\CatalogProductBundle\BundleSelections</source>
         </bundle_selections>
         <custom_options>
             <attribute_code>custom_options</attribute_code>
             <backend_type>virtual</backend_type>
             <group>product_info_tabs_customer_options</group>
             <is_required>0</is_required>
-            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</fixture>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</source>
         </custom_options>
     </fields>
     <data_set>
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0bb920f995d63aab6d1274acd55084a231a6467
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/BundleSelections.php
@@ -0,0 +1,338 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Bundle\Test\Fixture\CatalogProductBundle;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class BundleSelections
+ * "Selections" for the bundle product
+ */
+class BundleSelections implements FixtureInterface
+{
+    /**
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Current preset
+     *
+     * @var string
+     */
+    protected $currentPreset;
+
+    /**
+     * "Selections" source constructor
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @param array $data
+     * @param array $params [optional]
+     * @throws \Exception
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = [])
+    {
+        $this->params = $params;
+
+        if ($data['preset']) {
+            $this->currentPreset = $data['preset'];
+            $this->data = $this->getPreset($this->currentPreset);
+            if (!empty($data['products'])) {
+                $this->data['products'] = [];
+                $this->data['products'][] = explode(',', $data['products']);
+            }
+        }
+
+        if (!empty($this->data['products'])) {
+            $productsSelections = $this->data['products'];
+            $this->data['products'] = [];
+            foreach ($productsSelections as $products) {
+                $productSelection = [];
+                foreach ($products as $product) {
+                    list($fixture, $dataSet) = explode('::', $product);
+                    /** @var $productFixture InjectableFixture */
+                    $productFixture = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                    if (!$productFixture->hasData('id')) {
+                        $productFixture->persist();
+                    }
+                    $productSelection[] = $productFixture;
+                }
+                $this->data['products'][] = $productSelection;
+            }
+
+            foreach ($this->data['bundle_options'] as $optionKey => &$bundleOption) {
+                foreach ($bundleOption['assigned_products'] as $productKey => &$assignedProducts) {
+                    $assignedProducts['search_data']['name'] = $this->data['products'][$optionKey][$productKey]
+                        ->getName();
+                }
+                unset($bundleOption, $assignedProducts);
+            }
+        }
+    }
+
+    /**
+     * Persists prepared data into application
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Get selection for performing checkout
+     *
+     * @return array|null
+     */
+    public function getSelectionForCheckout()
+    {
+        /** @var \Magento\Catalog\Test\Fixture\CatalogProductSimple $product */
+        $product = reset($this->data['products'])[0];
+        $selectionsForCheckout = [
+            'default' => [
+                0 => [
+                    'value' => $product->getName(),
+                    'type' => 'select',
+                    'qty' => 1
+                ]
+            ],
+            'second' => [
+                0 => [
+                    'value' => $product->getName(),
+                    'type' => 'select',
+                    'qty' => 1
+                ]
+            ],
+        ];
+
+        if (!isset($selectionsForCheckout[$this->currentPreset])) {
+            return null;
+        }
+
+        return $selectionsForCheckout[$this->currentPreset];
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string|null $key [optional]
+     * @return mixed
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Getting preset data
+     *
+     * @param string $name
+     * @return mixed
+     * @throws \InvalidArgumentException
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function getPreset($name)
+    {
+        $presets = [
+            'default' => [
+                'bundle_options' => [
+                    [
+                        'title' => 'Drop-down Option',
+                        'type' => 'Drop-down',
+                        'required' => 'Yes',
+                        'assigned_products' => [
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_qty' => 1,
+                                ]
+                            ],
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_qty' => 1,
+                                ]
+                            ]
+                        ]
+                    ],
+                ],
+                'products' => [
+                    [
+                        'catalogProductSimple::default',
+                        'catalogProductSimple::default'
+                    ]
+                ]
+            ],
+            'default_dynamic' => [
+                'bundle_options' => [
+                    [
+                        'title' => 'Drop-down Option',
+                        'type' => 'Drop-down',
+                        'required' => 'Yes',
+                        'assigned_products' => [
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_qty' => 1,
+                                ]
+                            ],
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_qty' => 1,
+                                ]
+                            ]
+                        ]
+                    ],
+                ],
+                'products' => [
+                    [
+                        'catalogProductSimple::default',
+                        'catalogProductSimple::default'
+                    ]
+                ]
+            ],
+            'default_fixed' => [
+                'bundle_options' => [
+                    [
+                        'title' => 'Drop-down Option',
+                        'type' => 'Drop-down',
+                        'required' => 'Yes',
+                        'assigned_products' => [
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_price_value' => 5.00,
+                                    'selection_price_type' => 'Fixed',
+                                    'selection_qty' => 1,
+                                    'selection_can_change_qty' => 'Yes',
+                                ]
+                            ],
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_price_value' => 5.00,
+                                    'selection_price_type' => 'Fixed',
+                                    'selection_qty' => 1,
+                                    'selection_can_change_qty' => 'Yes',
+                                ]
+                            ]
+                        ]
+                    ],
+                ],
+                'products' => [
+                    [
+                        'catalogProductSimple::default',
+                        'catalogProductSimple::default'
+                    ]
+                ]
+            ],
+            'second' => [
+                'bundle_options' => [
+                    [
+                        'title' => 'Drop-down Option',
+                        'type' => 'Drop-down',
+                        'required' => 'Yes',
+                        'assigned_products' => [
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_price_value' => 5.00,
+                                    'selection_price_type' => 'Fixed',
+                                    'selection_qty' => 1,
+                                    'selection_can_change_qty' => 'Yes',
+                                ]
+                            ],
+                            [
+                                'search_data' => [
+                                    'name' => '%product_name%'
+                                ],
+                                'data' => [
+                                    'selection_price_value' => 10.00,
+                                    'selection_price_type' => 'Fixed',
+                                    'selection_qty' => 1,
+                                    'selection_can_change_qty' => 'Yes',
+                                ]
+                            ]
+                        ]
+                    ],
+                ],
+                'products' => [
+                    [
+                        'catalogProductSimple::default',
+                        'catalogProductSimple::default'
+                    ]
+                ]
+            ]
+        ];
+
+        if (!isset($presets[$name])) {
+            throw new \InvalidArgumentException(
+                sprintf('Wrong Bundle Selections preset name: %s', $name)
+            );
+        }
+
+        return $presets[$name];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Price.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php
similarity index 92%
rename from dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Price.php
rename to dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php
index b6f7c8faf76a1e361d47ceda7ec3d63964ed72cc..3a119dbf82f02d6a1e6219ebd24083a83ca2e540 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/Bundle/Price.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Fixture/CatalogProductBundle/Price.php
@@ -22,9 +22,8 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Bundle\Test\Fixture\Bundle;
+namespace Magento\Bundle\Test\Fixture\CatalogProductBundle;
 
-use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
 
 /**
@@ -104,27 +103,29 @@ class Price implements FixtureInterface
             'MAGETWO-23066' => [
                 'price_from' => '$115.00',
                 'price_to' => '$120.00',
-                'cart_price' => '$145.00'
+                'cart_price' => '145.00'
             ],
             'MAGETWO-23069' => [
                 'price_from' => '$115.00',
                 'price_to' => '$120.00',
-                'cart_price' => '$126.00'
+                'cart_price' => '126.00'
             ],
             'MAGETWO-23070' => [
                 'price_from' => '$40.00',
                 'price_to' => '$100.00',
-                'cart_price' => '$100.00'
+                'cart_price' => '100.00'
             ],
             'MAGETWO-23061' => [
                 'price_from' => '$32.00',
                 'price_to' => '$80.00',
-                'cart_price' => '$80.00'
+                'cart_price' => '80.00'
             ]
         ];
+
         if (!isset($presets[$this->currentPreset])) {
             return null;
         }
+
         return $presets[$this->currentPreset];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/CatalogProductBundleInterface.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/CatalogProductBundleInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..3829c810980cae2be39eda8ce9cded0dc64f1658
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/CatalogProductBundleInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Bundle\Test\Handler\CatalogProductBundle;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CatalogProductBundleInterface
+ */
+interface CatalogProductBundleInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/Curl.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..b30592d2ce7cb6e0c892f4a6cee1fce755bc0a87
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/CatalogProductBundle/Curl.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Bundle\Test\Handler\CatalogProductBundle;
+
+use Mtf\System\Config;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
+
+/**
+ * Class Curl
+ * Create new bundle product via curl
+ */
+class Curl extends ProductCurl implements CatalogProductBundleInterface
+{
+    /**
+     * Constructor
+     *
+     * @param Config $configuration
+     */
+    public function __construct(Config $configuration)
+    {
+        parent::__construct($configuration);
+
+        $this->mappingData += [
+            'selection_can_change_qty' => [
+                'Yes' => 1,
+                'No' => 0
+            ],
+            'sku_type' => [
+                'Dynamic' => 0,
+                'Fixed' => 1
+            ],
+            'price_type' => [
+                'Dynamic' => 0,
+                'Fixed' => 1
+            ],
+            'weight_type' => [
+                'Dynamic' => 0,
+                'Fixed' => 1
+            ],
+            'shipment_type' => [
+                'Together' => 0,
+                'Separately' => 1
+            ],
+            'type' => [
+                'Drop-down' => 'select',
+                'Radio Buttons' => 'radio',
+                'Checkbox' => 'checkbox',
+                'Multiple Select' => 'multi',
+            ],
+            'selection_price_type' => [
+                'Fixed' => 0,
+                'Percent' => 1
+            ]
+        ];
+    }
+
+    /**
+     * Prepare POST data for creating product request
+     *
+     * @param FixtureInterface $fixture
+     * @param string|null $prefix [optional]
+     * @return array
+     */
+    protected function prepareData(FixtureInterface $fixture, $prefix = null)
+    {
+        $data = parent::prepareData($fixture, null);
+
+        $selections = [];
+        $bundleSelections = [];
+        if (!empty($data['bundle_selections'])) {
+            $selections = $data['bundle_selections'];
+            $products = $selections['products'];
+            unset($data['selections'], $selections['products']);
+
+            foreach ($selections['bundle_options'] as $key => &$option) {
+                $option['delete'] = '';
+                $option['position'] = $key;
+                foreach ($option['assigned_products'] as $productKey => $assignedProduct) {
+                    $assignedProduct['data'] += [
+                        'product_id' => $products[$key][$productKey]->getId(),
+                        'delete' => '',
+                        'position' => $productKey
+                    ];
+                    $bundleSelections[$key][] = $assignedProduct['data'];
+                }
+                unset($option['assigned_products']);
+            }
+        }
+        $data = $prefix ? [$prefix => $data] : $data;
+        $data = array_merge($data, $selections);
+        $data['bundle_selections'] = $bundleSelections;
+
+        return $this->replaceMappingData($data);
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php
index 790c86b86cfcaee9ce9a3c9dd394751f0128230d..118f5679e772f29f4bcd78d204a0ceea9a609f18 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Handler/Curl/CreateBundle.php
@@ -25,27 +25,69 @@
 
 namespace Magento\Bundle\Test\Handler\Curl;
 
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Handler\Curl;
+use Mtf\System\Config;
+use Mtf\Fixture\FixtureInterface;
 use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
-use Mtf\System\Config;
 
 /**
+ * Class CreateBundle
  * Curl handler for creating bundle product.
- *
  */
 class CreateBundle extends Curl
 {
+    /**
+     * Mapping values for data.
+     *
+     * @var array
+     */
+    protected $mappingData = [
+        'selection_can_change_qty' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
+        'required' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
+        'sku_type' => [
+            'Dynamic' => 0,
+            'Fixed' => 1
+        ],
+        'price_type' => [
+            'Dynamic' => 0,
+            'Fixed' => 1
+        ],
+        'weight_type' => [
+            'Dynamic' => 0,
+            'Fixed' => 1
+        ],
+        'shipment_type' => [
+            'Together' => 0,
+            'Separately' => 1
+        ],
+        'type' => [
+            'Drop-down' => 'select',
+            'Radio Buttons' => 'radio',
+            'Checkbox' => 'checkbox',
+            'Multiple Select' => 'multi',
+        ],
+        'selection_price_type' => [
+            'Fixed' => 0,
+            'Percent' => 1
+        ]
+    ];
+
     /**
      * Prepare POST data for creating bundle product request
      *
      * @param array $params
-     * @param string|null $prefix
+     * @param string|null $prefix [optional]
      * @return array
      */
-    protected function _prepareData($params, $prefix = null)
+    protected function _prepareData(array $params, $prefix = null)
     {
         $data = array();
         foreach ($params as $key => $values) {
@@ -53,7 +95,7 @@ class CreateBundle extends Curl
                 $data = array_merge($data, $this->_getBundleData($values['value']));
             } else {
                 $value = $this->_getValue($values);
-                //do not add this data if value does not exist
+                // do not add this data if value does not exist
                 if (null === $value) {
                     continue;
                 }
@@ -67,6 +109,7 @@ class CreateBundle extends Curl
                 }
             }
         }
+
         return $data;
     }
 
@@ -76,7 +119,7 @@ class CreateBundle extends Curl
      * @param array $values
      * @return null|mixed
      */
-    protected function _getValue($values)
+    protected function _getValue(array $values)
     {
         if (!isset($values['value'])) {
             return null;
@@ -90,17 +133,34 @@ class CreateBundle extends Curl
      * @param array $params
      * @return array
      */
-    protected function _getBundleData($params)
+    protected function _getBundleData(array $params)
     {
-        $data = array();
-        foreach ($params as $options) {
-            if (isset($options['assigned_products'])) {
-                $data['bundle_selections'][] = $this->_getSelections($options['assigned_products']);
-                unset($options['assigned_products']);
+        $data = [
+            'bundle_options' => [],
+            'bundle_selections' => []
+        ];
+        $index = 0;
+        foreach ($params['bundle_options'] as $option) {
+            $data['bundle_options'][] = [
+                'title' => $option['title'],
+                'type' => $option['type'],
+                'required' => $option['required'],
+                'delete' => '',
+                'position' => $index
+            ];
+
+            $position = 0;
+            foreach ($option['assigned_products'] as $assignedProduct) {
+                $assignedProduct['data'] += [
+                    'delete' => '',
+                    'position' => ++$position
+                ];
+                $data['bundle_selections'][$index][] = $assignedProduct['data'];
             }
-            $data['bundle_options'][] = $this->_prepareData($options) + ['delete' => ''];
+            ++$index;
         }
-        return $data;
+
+        return $this->replaceMappingData($data);
     }
 
     /**
@@ -125,7 +185,7 @@ class CreateBundle extends Curl
      * @param array $products
      * @return array
      */
-    protected function _getSelections($products)
+    protected function _getSelections(array $products)
     {
         $data = array();
         foreach ($products as $product) {
@@ -138,7 +198,7 @@ class CreateBundle extends Curl
     /**
      * Post request for creating bundle product
      *
-     * @param FixtureInterface $fixture [optional]
+     * @param FixtureInterface|null $fixture [optional]
      * @return mixed|string
      * @throws \Exception
      */
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php
index 1f00d14261baa5a2cbcd637a856f776bde411c04..36d9d4e624eba64a487c896fcd6c4e6ab04efad7 100644
--- a/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/Repository/CatalogProductBundle.php
@@ -28,13 +28,15 @@ use Mtf\Repository\AbstractRepository;
 
 /**
  * Class CatalogProductBundle
- *
+ * Data for creation Catalog Product Bundle
  */
 class CatalogProductBundle extends AbstractRepository
 {
     /**
-     * @param array $defaultConfig
-     * @param array $defaultData
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
@@ -49,11 +51,11 @@ class CatalogProductBundle extends AbstractRepository
             ],
             'short_description' => '',
             'description' => '',
-            'tax_class_id' => '2',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
             'sku_type' => '0',
             'price_type' => '0',
             'weight_type' => '0',
-            'status' => '1',
+            'status' => 'Product online',
             'shipment_type' => '1',
             'mtf_dataset_name' => 'BundleDynamic_sku_1073507449'
         ];
@@ -67,12 +69,65 @@ class CatalogProductBundle extends AbstractRepository
             ],
             'short_description' => '',
             'description' => '',
-            'tax_class_id' => '2',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
             'sku_type' => '0',
             'weight_type' => '0',
             'price_type' => '0',
             'shipment_type' => '1',
             'mtf_dataset_name' => 'BundleDynamic_sku_215249172'
         ];
+
+        $this->_data['bundle_dynamic_product'] = [
+            'name' => 'Bundle dynamic product %isolation%',
+            'sku' => 'sku_bundle_dynamic_product_%isolation%',
+            'sku_type' => 'Dynamic',
+            'price_type' => 'Dynamic',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'weight_type' => 'Dynamic',
+            'shipment_type' => 'Separately',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'website_ids' => ['Main Website'],
+            'stock_data' => [
+                'manage_stock' => 'Yes',
+                'use_config_enable_qty_increments' => 'Yes',
+                'use_config_qty_increments' => 'Yes',
+                'is_in_stock' => 'In Stock'
+            ],
+            'url_key' => 'bundle-dynamic-product-%isolation%',
+            'visibility' => 'Catalog, Search',
+            'bundle_selections' => ['preset' => 'default_dynamic'],
+            'attribute_set_id' => 'Default',
+        ];
+
+        $this->_data['bundle_fixed_product'] = [
+            'name' => 'Bundle fixed product %isolation%',
+            'sku' => 'sku_bundle_fixed_product_%isolation%',
+            'sku_type' => 'Fixed',
+            'price_type' => 'Fixed',
+            'price' => ['value' => 750.00, 'preset' => '-'],
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'weight' => 1.0000,
+            'weight_type' => 'Fixed',
+            'status' => 'Product online',
+            'shipment_type' => 'Together',
+            'website_ids' => ['Main Website'],
+            'stock_data' => [
+                'manage_stock' => 'Yes',
+                'use_config_enable_qty_increments' => 'Yes',
+                'use_config_qty_increments' => 'Yes',
+                'is_in_stock' => 'In Stock'
+            ],
+            'url_key' => 'bundle-fixed-product-%isolation%',
+            'visibility' => 'Catalog, Search',
+            'bundle_selections' => ['preset' => 'default_fixed'],
+            'attribute_set_id' => 'Default',
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3d8c6b53493ed2d19d62cc9335feaef82e0fe630
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Bundle/Test/etc/curl/di.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\Bundle\Test\Handler\CatalogProductBundle\CatalogProductBundleInterface" type="Magento\Bundle\Test\Handler\CatalogProductBundle\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
index 5968fa622e4f10a9799dbb6eb4d02c39da9b4aba..5db9812bcfe59206ff262f156d8c79d5a9e5c945 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/CategoryForm.xml
@@ -75,7 +75,7 @@
         <wrapper>general</wrapper>
     </custom_design>
     <category_products>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
+        <class>\Magento\Catalog\Test\Block\Adminhtml\Category\Edit\Tab\Product</class>
         <selector>#category_info_tabs_products</selector>
         <strategy>css selector</strategy>
     </category_products>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Tab/Product.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Tab/Product.php
new file mode 100644
index 0000000000000000000000000000000000000000..8edbde808dd7b80148bb8355acaac56858e9e7e4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Edit/Tab/Product.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Block\Adminhtml\Category\Edit\Tab;
+
+use Mtf\Client\Element;
+use Magento\Backend\Test\Block\Widget\Tab;
+use Magento\Catalog\Test\Block\Adminhtml\Category\Tab\ProductGrid;
+
+/**
+ * Class Product
+ * Products grid of Category Products tab
+ */
+class Product extends Tab
+{
+    /**
+     * An element locator which allows to select entities in grid
+     *
+     * @var string
+     */
+    protected $selectItem = 'tbody tr .col-in_category';
+
+    /**
+     * Product grid locator
+     *
+     * @var string
+     */
+    protected $productGrid = '#catalog_category_products';
+
+    /**
+     * Fill category products
+     *
+     * @param array $fields
+     * @param Element|null $element
+     * @return void
+     */
+    public function fillFormTab(array $fields, Element $element = null)
+    {
+        if (!isset($fields['category_products'])) {
+            return;
+        }
+        foreach ($fields['category_products']['source']->getData() as $productName) {
+            $this->getProductGrid()->searchAndSelect(['name' => $productName]);
+        }
+    }
+
+    /**
+     * Returns role grid
+     *
+     * @return ProductGrid
+     */
+    public function getProductGrid()
+    {
+        return $this->blockFactory->create(
+            'Magento\Catalog\Test\Block\Adminhtml\Category\Tab\ProductGrid',
+            ['element' => $this->_rootElement->find($this->productGrid)]
+        );
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tab/ProductGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tab/ProductGrid.php
index f93006df9c596f21ccc8e4be9bbef1fbcb79af5b..ddc18bc0686c5c32334fb8478448a297ddf4cfff 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tab/ProductGrid.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tab/ProductGrid.php
@@ -29,7 +29,6 @@ use Magento\Backend\Test\Block\Widget\Grid;
 /**
  * Class ProductGrid
  * Products' grid of Category Products tab
- *
  */
 class ProductGrid extends Grid
 {
@@ -41,6 +40,9 @@ class ProductGrid extends Grid
     protected $filters = [
         'sku' => [
             'selector' => '#catalog_category_products_filter_sku'
+        ],
+        'name' => [
+            'selector' => '#catalog_category_products_filter_name'
         ]
     ];
 
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
index c2d27a7285d60ea48274714a09792d93e657e36d..ac5b68dfd8ae6e9e9ac27199333ebee7a2864df9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Category/Tree.php
@@ -43,7 +43,14 @@ class Tree extends Block
      *
      * @var string
      */
-    protected $addSubcategory = 'add_subcategory_button';
+    protected $addSubcategory = '#add_subcategory_button';
+
+    /**
+     * 'Add Root Category' button
+     *
+     * @var string
+     */
+    protected $addRootCategory = '#add_root_category_button';
 
     /**
      * 'Expand All' link
@@ -73,8 +80,9 @@ class Tree extends Block
      */
     protected function getTemplateBlock()
     {
-        return Factory::getBlockFactory()->getMagentoBackendTemplate(
-            $this->_rootElement->find($this->templateBlock, Locator::SELECTOR_XPATH)
+        return $this->blockFactory->create(
+            'Magento\Backend\Test\Block\Template',
+            ['element' => $this->_rootElement->find($this->templateBlock, Locator::SELECTOR_XPATH)]
         );
     }
 
@@ -85,7 +93,18 @@ class Tree extends Block
      */
     public function addSubcategory()
     {
-        $this->_rootElement->find($this->addSubcategory, Locator::SELECTOR_ID)->click();
+        $this->_rootElement->find($this->addSubcategory, Locator::SELECTOR_CSS)->click();
+        $this->getTemplateBlock()->waitLoader();
+    }
+
+    /**
+     * Press 'Add Root Category' button
+     *
+     * @return void
+     */
+    public function addRootCategory()
+    {
+        $this->_rootElement->find($this->addRootCategory, Locator::SELECTOR_CSS)->click();
         $this->getTemplateBlock()->waitLoader();
     }
 
@@ -93,12 +112,16 @@ class Tree extends Block
      * Select Default category
      *
      * @param FixtureInterface $category
+     * @param bool $fullPath
      * @return void
      */
-    public function selectCategory(FixtureInterface $category)
+    public function selectCategory(FixtureInterface $category, $fullPath = true)
     {
         if ($category instanceof InjectableFixture) {
             $parentPath = $this->prepareFullCategoryPath($category);
+            if (!$fullPath) {
+                array_pop($parentPath);
+            }
             $path = implode('/', $parentPath);
         } else {
             $path = $category->getCategoryPath();
@@ -118,10 +141,10 @@ class Tree extends Block
     protected function prepareFullCategoryPath(CatalogCategory $category)
     {
         $path = [];
-        if ($category->getDataFieldConfig('parent_id')['source']->getParentCategory() != null) {
-            $path = $this->prepareFullCategoryPath(
-                $category->getDataFieldConfig('parent_id')['source']->getParentCategory()
-            );
+        $parentCategory = $category->getDataFieldConfig('parent_id')['source']->getParentCategory();
+
+        if ($parentCategory != null) {
+            $path = $this->prepareFullCategoryPath($parentCategory);
         }
         return array_filter(array_merge($path, [$category->getPath(), $category->getName()]));
     }
@@ -150,10 +173,10 @@ class Tree extends Block
     /**
      * Check category in category tree
      *
-     * @param $category
+     * @param CatalogCategory $category
      * @return bool
      */
-    public function isCategoryVisible($category)
+    public function isCategoryVisible(CatalogCategory $category)
     {
         $categoryPath = $this->prepareFullCategoryPath($category);
         $structure = $this->_rootElement->find($this->treeElement, Locator::SELECTOR_CSS, 'tree')->getStructure();
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php
index 404906dc4c771dd25843373ae8c5ea8f643c2e71..611c058c430b746b066c880efb99184c0981f397 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product.php
@@ -39,14 +39,14 @@ class Product extends Block
      *
      * @var string
      */
-    protected $toggleButton = '[data-ui-id=products-list-add-new-button-dropdown]';
+    protected $toggleButton = '[data-ui-id=products-list-add-new-product-button-dropdown]';
 
     /**
      * Product type item
      *
      * @var string
      */
-    protected $productItem = '[data-ui-id=products-list-add-new-button-item-%productType%]';
+    protected $productItem = '[data-ui-id=products-list-add-new-product-button-item-%productType%]';
 
     /**
      * Add product using split button
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php
index 57aba39bd3328ce8403010df4e08ac832b3114ac..24a229b390b6c2198930692ec922975d2c754737 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.php
@@ -29,8 +29,8 @@ use Mtf\Client\Element;
 use Magento\Backend\Test\Block\Widget\Form;
 
 /**
+ * Class Attribute
  * Product attribute massaction edit page
- *
  */
 class Attribute extends Form
 {
@@ -46,13 +46,19 @@ class Attribute extends Form
      *
      * @var string
      */
-    protected $priceFieldEnablerSelector = '//*[@id="attribute-price-container"]/div[1]/div/label/span';
+    protected $priceFieldEnablerSelector = '//*[@id="attribute-price-container"]/div[1]/div/label//*[@type="checkbox"]';
 
     /**
      * Enable price field editing
+     *
+     * @return void
      */
     public function enablePriceEdit()
     {
-        $this->_rootElement->find($this->priceFieldEnablerSelector, Element\Locator::SELECTOR_XPATH)->click();
+        $this->_rootElement->find(
+            $this->priceFieldEnablerSelector,
+            Element\Locator::SELECTOR_XPATH,
+            'checkbox'
+        )->setValue('Yes');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7fd3acd7908b64e4c0f25ed1a995a2bfda683818
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Action/Attribute.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <wrapper>attributes</wrapper>
+    <fields>
+        <price/>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
index 15519e22b001c69e51cb134b7a73994b3867d0cd..3f197b91ebb8a72ad7242e65c268d15daaf52ef3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Crosssell.php
@@ -30,8 +30,8 @@ use Magento\Backend\Test\Block\Widget\Tab;
 use Mtf\Factory\Factory;
 
 /**
+ * Class Crosssell
  * Cross-sell Tab
- *
  */
 class Crosssell extends Tab
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
index 93f5243e9b632122004599f8909eb9351fe40875..27e9304a6d70a0bf3cebfbb3d9a06a3b237aadfc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Related.php
@@ -30,8 +30,8 @@ use Mtf\Factory\Factory;
 use Magento\Backend\Test\Block\Widget\Tab;
 
 /**
+ * Class Related
  * Related Tab
- *
  */
 class Related extends Tab
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
index 592ed95817c33e8f4f77f9d8955dbb5f11f47de6..aefe47026b037ece7c9a025324ef158135765574 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
@@ -151,9 +151,19 @@ class Config extends Tab
      * @param array $fields
      * @return void
      */
-    public function fillVariationsMatrix($fields)
+    public function fillVariationsMatrix(array $fields)
     {
-        $this->getMatrixBlock()->fillVariation($fields);
+        $variations = [];
+        foreach ($fields as $key => $field) {
+            foreach ($field['value'] as $fieldName => $value) {
+                $variations[$key][$fieldName] = $value['value'];
+            }
+            foreach ($field['configurable_attribute'] as $options) {
+                $variations[$key]['options_names'][] = $options['attribute_option'];
+            }
+        }
+
+        $this->getMatrixBlock()->fillVariation($variations);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
index c43f787dbe2ebc06f103b1a741bb5a566a8daa77..2aa9fdefb67b7087d49b24bf93510b981f6338cc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config/Matrix.php
@@ -31,7 +31,6 @@ use Mtf\Client\Element\Locator;
 /**
  * Class Matrix
  * Product variations matrix block
- *
  */
 class Matrix extends Form
 {
@@ -39,18 +38,19 @@ class Matrix extends Form
      * Fill qty to current variations
      *
      * @param array $variations
+     * @return void
      */
     public function fillVariation(array $variations)
     {
         foreach ($variations as $variation) {
-            $variationRow = $this->getVariationRow($variation['configurable_attribute']);
-            foreach ($variation['value'] as $key => $field) {
+            $variationRow = $this->getVariationRow($variation['options_names']);
+            foreach ($variation as $key => $value) {
                 if (!empty($this->mapping[$key])) {
                     $this->_rootElement->find(
                         $variationRow . $this->mapping[$key]['selector'],
                         Locator::SELECTOR_XPATH,
                         isset($this->mapping[$key]['input']) ? $this->mapping[$key]['input'] : null
-                    )->setValue($field['value']);
+                    )->setValue($value);
                 }
             }
         }
@@ -60,13 +60,13 @@ class Matrix extends Form
      * Define row that clarifies which line in Current Variations grid will be used
      *
      * @param array $variationData
-     * @return Element
+     * @return string
      */
     private function getVariationRow(array $variationData)
     {
         $options = array();
         foreach ($variationData as $attributeData) {
-            $options[] = 'td[text()="' . $attributeData['attribute_option'] . '"]';
+            $options[] = 'td[text()="' . $attributeData . '"]';
         }
 
         return '//tr[' . implode(' and ', $options) . ']';
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
index 752d50ecb197795479feee504927f96ffeadf016..79464bf426e9f788df725b7cb3facff0abc9c775 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/Edit/Tab/Upsell.php
@@ -30,8 +30,8 @@ use Magento\Backend\Test\Block\Widget\Tab;
 use Mtf\Factory\Factory;
 
 /**
+ * Class Upsell
  * Upsell Tab
- *
  */
 class Upsell extends Tab
 {
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
old mode 100644
new mode 100755
index 98a84c8f89ee62807ac37040dbb5a181dbf640ab..8e443f1eac124d5569eaa26a34c87aab6b3548a3
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Adminhtml/Product/ProductForm.xml
@@ -44,12 +44,14 @@
                 <is_virtual>
                     <input>checkbox</input>
                 </is_virtual>
-                <qty>
-                    <selector>#qty</selector>
-                </qty>
-                <quantity_and_stock_status>
-                    <selector>#quantity_and_stock_status</selector>
-                    <input>select</input>
+                <quantity_and_stock_status composite="1">
+                    <qty>
+                        <selector>#qty</selector>
+                    </qty>
+                    <is_in_stock>
+                        <selector>#quantity_and_stock_status</selector>
+                        <input>select</input>
+                    </is_in_stock>
                 </quantity_and_stock_status>
                 <description>
                     <selector>#description</selector>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
index c48b11994b6eeeff59ab4baf623b4970a378c63f..3d80fabc9215167f0e1a7683a10513de386f90b3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Block/Product/View/CustomOptions.php
@@ -145,11 +145,8 @@ class CustomOptions extends Block
                     $option['value'][] = $value;
                     $option['price'][] = $matches[1];
                 }
-            } elseif (($prices = $fieldElement->find(
-                $this->selectLocator,
-                Locator::SELECTOR_XPATH
-            )
-                ) && $prices->isVisible()
+            } elseif (($prices = $fieldElement->find($this->selectLocator, Locator::SELECTOR_XPATH))
+                && $prices->isVisible()
             ) {
                 $priceIndex = 0;
                 while (($price = $prices->find(sprintf($this->optionLocator, ++$priceIndex), Locator::SELECTOR_XPATH))
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForAssignedProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForAssignedProducts.php
new file mode 100644
index 0000000000000000000000000000000000000000..5e1ec3fc7bfce0ecec0a78f3899b304693468c7f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryForAssignedProducts.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+
+/**
+ * Class AssertCategoryForAssignedProducts
+ * Assert that displayed assigned products on category page equals passed from fixture
+ */
+class AssertCategoryForAssignedProducts extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that displayed assigned products on category page equals passed from fixture
+     *
+     * @param CatalogCategory $category
+     * @param CatalogCategoryView $categoryView
+     * @param Browser $browser
+     * @return void
+     */
+    public function processAssert(CatalogCategory $category, CatalogCategoryView $categoryView, Browser $browser)
+    {
+        $browser->open($_ENV['app_frontend_url'] . strtolower($category->getUrlKey()) . '.html');
+        $products = $category->getDataFieldConfig('category_products')['source']->getProducts();
+        foreach ($products as $productFixture) {
+            \PHPUnit_Framework_Assert::assertTrue(
+                $categoryView->getListProductBlock()->isProductVisible($productFixture->getName()),
+                "Products '{$productFixture->getName()}' not find."
+            );
+        }
+    }
+
+    /**
+     * Displayed assigned products on category page equals passed from fixture
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Displayed assigned products on category page equal to passed from fixture.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotActive.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotActive.php
new file mode 100644
index 0000000000000000000000000000000000000000..0be75010bf9facf4ae94c929c6ea24d747f701bf
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotActive.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+
+/**
+ * Class AssertCategoryIsNotActive
+ * Assert that the category cannot be accessed from the navigation bar in the frontend
+ */
+class AssertCategoryIsNotActive extends AbstractConstraint
+{
+    const NOT_FOUND_MESSAGE = 'Whoops, our bad...';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that the category cannot be accessed from the navigation bar in the frontend
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategory $category
+     * @param Browser $browser
+     * @return void
+     */
+    public function processAssert(CmsIndex $cmsIndex, CatalogCategory $category, Browser $browser)
+    {
+        $cmsIndex->open();
+        \PHPUnit_Framework_Assert::assertFalse(
+            $cmsIndex->getTopmenu()->isCategoryVisible($category->getName()),
+            'Category can be accessed from the navigation bar in the frontend.'
+        );
+        $browser->open($_ENV['app_frontend_url'] . $category->getUrlKey() . '.html');
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::NOT_FOUND_MESSAGE,
+            $cmsIndex->getTitleBlock()->getTitle(),
+            'Wrong page is displayed.'
+        );
+    }
+
+    /**
+     * Category not find in top menu
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Category cannot be accessed from the navigation bar.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotIncludeInMenu.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotIncludeInMenu.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d7dadbffd2f7e4bd33d6f2a46ae783dfc6429f8
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertCategoryIsNotIncludeInMenu.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
+
+/**
+ * Class AssertCategoryIsNotIncludeInMenu
+ * Assert that the category is no longer available on the top menu bar
+ */
+class AssertCategoryIsNotIncludeInMenu extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that the category is no longer available on the top menu bar
+     *
+     * @param CmsIndex $cmsIndex
+     * @param CatalogCategory $category
+     * @param Browser $browser
+     * @param CatalogCategoryView $categoryView
+     * @return void
+     */
+    public function processAssert(
+        CmsIndex $cmsIndex,
+        CatalogCategory $category,
+        Browser $browser,
+        CatalogCategoryView $categoryView
+    ) {
+        $cmsIndex->open();
+        \PHPUnit_Framework_Assert::assertFalse(
+            $cmsIndex->getTopmenu()->isCategoryVisible($category->getName()),
+            'Category can be accessed from the navigation bar in the frontend.'
+        );
+
+        $browser->open($_ENV['app_frontend_url'] . $category->getUrlKey() . '.html');
+        \PHPUnit_Framework_Assert::assertEquals(
+            $category->getName(),
+            $categoryView->getTitleBlock()->getTitle(),
+            'Wrong page is displayed.'
+        );
+        if (isset($category->getDataFieldConfig('category_products')['source'])) {
+            $products = $category->getDataFieldConfig('category_products')['source']->getProducts();
+            foreach ($products as $productFixture) {
+                \PHPUnit_Framework_Assert::assertTrue(
+                    $categoryView->getListProductBlock()->isProductVisible($productFixture->getName()),
+                    "Products '{$productFixture->getName()}' not find."
+                );
+            }
+        }
+    }
+
+    /**
+     * Category is no longer available on the top menu bar, but can be viewed by URL with all assigned products
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Category is not on the top menu bar, but can be viewed by URL.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
index c50605708666b4d486ebfe11ead386b1d9a93a49..97378c339816e27f7aa5323c131c79e1576f414e 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductIsNotDisplayingOnFrontend.php
@@ -47,7 +47,42 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
      *
      * @var string
      */
-    protected $severeness = 'low';
+    protected $severeness = 'high';
+
+    /**
+     * Product view page
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Catalog category view page
+     *
+     * @var CatalogCategoryView
+     */
+    protected $catalogCategoryView;
+
+    /**
+     * Catalog search result page
+     *
+     * @var CatalogsearchResult
+     */
+    protected $catalogSearchResult;
+
+    /**
+     * Cms index page
+     *
+     * @var CmsIndex
+     */
+    protected $cmsIndex;
+
+    /**
+     * Fixture category
+     *
+     * @var CatalogCategory
+     */
+    protected $category;
 
     /**
      * Assert that product with current configurations is not displayed on front-end
@@ -56,7 +91,7 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
      * @param CatalogsearchResult $catalogSearchResult
      * @param CatalogCategoryView $catalogCategoryView
      * @param CmsIndex $cmsIndex
-     * @param FixtureInterface $product
+     * @param FixtureInterface|FixtureInterface[] $product
      * @param CatalogCategory $category
      */
     public function processAssert(
@@ -64,43 +99,69 @@ class AssertProductIsNotDisplayingOnFrontend extends AbstractConstraint
         CatalogsearchResult $catalogSearchResult,
         CatalogCategoryView $catalogCategoryView,
         CmsIndex $cmsIndex,
-        FixtureInterface $product,
+        $product,
         CatalogCategory $category
     ) {
+        $this->catalogProductView = $catalogProductView;
+        $this->catalogSearchResult = $catalogSearchResult;
+        $this->catalogCategoryView = $catalogCategoryView;
+        $this->cmsIndex = $cmsIndex;
+        $this->category = $category;
+        $products = is_array($product) ? $product : [$product];
+        $errors = [];
+        foreach ($products as $product) {
+            $errors = array_merge($errors, $this->isNotDisplayingOnFrontendAssert($product));
+        }
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errors),
+            "In the process of checking product availability on the frontend, found the following errors:\n"
+            . implode("\n", $errors)
+        );
+    }
+
+
+    /**
+     * Verify product displaying on frontend
+     *
+     * @param FixtureInterface $product
+     * @return array
+     */
+    protected function isNotDisplayingOnFrontendAssert(FixtureInterface $product)
+    {
         $errors = [];
         // Check the product page is not available
         // TODO fix initialization url for frontend page
-        $catalogProductView->init($product);
-        $catalogProductView->open();
-        $titleBlock = $catalogProductView->getTitleBlock();
+        $this->catalogProductView->init($product);
+        $this->catalogProductView->open();
+        $titleBlock = $this->catalogProductView->getTitleBlock();
 
         if ($titleBlock->getTitle() !== self::NOT_FOUND_MESSAGE) {
             $errors[] = '- the headline on the page does not match, the text should be -> "'
                 . self::NOT_FOUND_MESSAGE . '".';
         }
 
-        $cmsIndex->open();
-        $cmsIndex->getSearchBlock()->search($product->getSku());
-        if ($catalogSearchResult->getListProductBlock()->isProductVisible($product->getName())) {
+        $this->cmsIndex->open();
+        $this->cmsIndex->getSearchBlock()->search($product->getSku());
+        if ($this->catalogSearchResult->getListProductBlock()->isProductVisible($product->getName())) {
             $errors[] = '- successful product search.';
         }
 
-        $cmsIndex->open();
-        $cmsIndex->getTopmenu()->selectCategoryByName($category->getName());
-        $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
-        while (!$isProductVisible && $catalogCategoryView->getToolbar()->nextPage()) {
-            $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        $categoryName = ($product->hasData('category_ids'))
+            ? $product->getCategoryIds()[0]['name']
+            : $this->category->getName();
+        $this->cmsIndex->open();
+        $this->cmsIndex->getTopmenu()->selectCategoryByName($categoryName);
+        $isProductVisible = $this->catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
+        while (!$isProductVisible && $this->catalogCategoryView->getToolbar()->nextPage()) {
+            $isProductVisible = $this->catalogCategoryView->getListProductBlock()
+                ->isProductVisible($product->getName());
         }
 
         if ($isProductVisible) {
-            $errors[] = '- product found in this category.';
+            $errors[] = '- product with name "{$product->getName()}" is found in this category.';
         }
 
-        \PHPUnit_Framework_Assert::assertTrue(
-            empty($errors),
-            "In the process of checking product availability on the frontend, found the following errors:\n"
-            . implode("\n", $errors)
-        );
+        return $errors;
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..a1811ddfa2231a4204db69b231e988e252187612
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductNotInGrid.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+
+/**
+ * Class AssertProductNotInGrid
+ */
+class AssertProductNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that product cannot be found by name and sku.
+     *
+     * @param FixtureInterface|FixtureInterface[] $product
+     * @param CatalogProductIndex $productGrid
+     * @return void
+     */
+    public function processAssert($product, CatalogProductIndex $productGrid)
+    {
+        $products = is_array($product) ? $product : [$product];
+        foreach ($products as $product) {
+            $filter = ['sku' => $product->getSku(), 'name' => $product->getName()];
+            $productGrid->open();
+            \PHPUnit_Framework_Assert::assertFalse(
+                $productGrid->getProductGrid()->isRowVisible($filter),
+                "Product with sku \"{$filter['sku']}\" and name \"{$filter['name']}\" is attend in Products grid."
+            );
+        }
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Assertion that product is absent in products grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
index 7316ea2c1e39b7be3c5645189a79572453b05111..ffd5b5de0a9e36ca4cc085ffaf67dfd7255b62b9 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSearchableBySku.php
@@ -71,7 +71,10 @@ class AssertProductSearchableBySku extends AbstractConstraint
         $cmsIndex->open();
         $cmsIndex->getSearchBlock()->search($product->getSku());
 
-        if ($product->getVisibility() === 'Catalog' || $product->getQuantityAndStockStatus() === 'Out of Stock') {
+        $isInStock = $product->getQuantityAndStockStatus();
+        if ($product->getVisibility() === 'Catalog'
+            || (isset($isInStock['is_in_stock']) && $isInStock['is_in_stock'] === 'Out of Stock')
+        ) {
             $isVisible = !($catalogSearchResult->getListProductBlock()->isProductVisible($product->getName()));
             $this->errorMessage = 'Product successfully found by SKU.';
             $this->successfulMessage = 'The product has not been found by SKU.';
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSuccessDeleteMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..4c4ba71ed7e91ee4cb8660da8609e09cb9909fb7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductSuccessDeleteMessage.php
@@ -0,0 +1,78 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Constraint;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex;
+
+/**
+ * Class AssertProductSuccessDeleteMessage
+ */
+class AssertProductSuccessDeleteMessage extends AbstractConstraint
+{
+    /**
+     * Text value to be checked
+     */
+    const SUCCESS_DELETE_MESSAGE = 'A total of %d record(s) have been deleted.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that after deleting product success message.
+     *
+     * @param FixtureInterface|FixtureInterface[] $product
+     * @param CatalogProductIndex $productPage
+     * @return void
+     */
+    public function processAssert($product, CatalogProductIndex $productPage)
+    {
+        $products = is_array($product) ? $product : [$product];
+        $deleteMessage = sprintf(self::SUCCESS_DELETE_MESSAGE, count($products));
+        $actualMessage = $productPage->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            $deleteMessage,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . $deleteMessage
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Returns a string representation of the object.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Assertion that products success delete message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
index 09e782d177d97728feb72dcd9b02fa58f91b388a..04e4727a32ffc6be3c8e3dc718234470c1622e93 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Constraint/AssertProductVisibleInCategory.php
@@ -80,7 +80,10 @@ class AssertProductVisibleInCategory extends AbstractConstraint
             $isProductVisible = $catalogCategoryView->getListProductBlock()->isProductVisible($product->getName());
         }
 
-        if ($product->getVisibility() === 'Search' || $product->getQuantityAndStockStatus() === 'Out of Stock') {
+        $isInStock = $product->getQuantityAndStockStatus();
+        if ($product->getVisibility() === 'Search'
+            || (isset($isInStock['is_in_stock']) && $isInStock['is_in_stock'] === 'Out of Stock')
+        ) {
             $isProductVisible = !$isProductVisible;
             $this->errorMessage = 'Product found in this category.';
             $this->successfulMessage = 'Asserts that the product could not be found in this category.';
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
index 0f187b98e853a133b3661fe54d935680955f5594..dff2a59d98b510f5edd81bcf26f30c21cb592d4c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.php
@@ -91,6 +91,7 @@ class CatalogCategory extends InjectableFixture
         'is_required' => '',
         'default_value' => '0',
         'input' => '',
+        'group' => null,
         'source' => 'Magento\Catalog\Test\Fixture\CatalogCategory\ParentId',
     ];
 
@@ -115,6 +116,7 @@ class CatalogCategory extends InjectableFixture
         'backend_type' => 'varchar',
         'is_required' => '',
         'default_value' => '',
+        'group' => null,
         'input' => '',
     ];
 
@@ -189,6 +191,7 @@ class CatalogCategory extends InjectableFixture
     protected $id = [
         'attribute_code' => 'id',
         'backend_type' => 'virtual',
+        'group' => null,
     ];
 
     protected $name = [
@@ -211,6 +214,13 @@ class CatalogCategory extends InjectableFixture
         'backend_type' => 'virtual',
     ];
 
+    protected $category_products = [
+        'attribute_code' => 'category_products',
+        'backend_type' => 'virtual',
+        'group' => 'category_products',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogCategory\CategoryProducts',
+    ];
+
     public function getEntityId()
     {
         return $this->getData('entity_id');
@@ -315,4 +325,9 @@ class CatalogCategory extends InjectableFixture
     {
         return $this->getData('include_in_menu');
     }
+
+    public function getCategoryProducts()
+    {
+        return $this->getData('category_products');
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
index 2f68c4b8c43a8393064f3e6e53e41b5d9601b43b..ab2369fc54af0e76b01621345ca730fc3fe90525 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory.xml
@@ -162,6 +162,11 @@
             <attribute_code>include_in_menu</attribute_code>
             <backend_type>virtual</backend_type>
         </include_in_menu>
+        <category_products>
+            <attribute_code>category_products</attribute_code>
+            <backend_type>virtual</backend_type>
+            <source>Magento\Catalog\Test\Fixture\CatalogCategory\CategoryProducts</source>
+        </category_products>
     </fields>
     <repository_class>Magento\Catalog\Test\Repository\CatalogCategory</repository_class>
     <handler_interface>Magento\Catalog\Test\Handler\CatalogCategory\CatalogCategoryInterface</handler_interface>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/CategoryProducts.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/CategoryProducts.php
new file mode 100644
index 0000000000000000000000000000000000000000..ff635fd967cc4505f6032b68b42d464df4bcfee9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogCategory/CategoryProducts.php
@@ -0,0 +1,123 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Fixture\CatalogCategory;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\FixtureFactory;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+
+/**
+ * Class CategoryProducts
+ * Prepare products
+ */
+class CategoryProducts implements FixtureInterface
+{
+    /**
+     * Prepared dataSet data
+     *
+     * @var array|null
+     */
+    protected $data;
+
+    /**
+     * Return products
+     *
+     * @var array
+     */
+    protected $products = [];
+
+    /**
+     * Fixture params
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * @constructor
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array|int $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, $data = [])
+    {
+        $this->params = $params;
+        if (!empty($data['dataSet']) && $data['dataSet'] !== '-') {
+            $dataSet = explode(',', $data['dataSet']);
+            foreach ($dataSet as $value) {
+                $explodeValue = explode('::', $value);
+                $product = $fixtureFactory->createByCode($explodeValue[0], ['dataSet' => $explodeValue[1]]);
+                if (!$product->getId()) {
+                    $product->persist();
+                }
+                $this->data[] = $product->getName();
+                $this->products[] = $product;
+            }
+        }
+    }
+
+    /**
+     * Persist attribute options
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string|null $key [optional]
+     * @return array|null
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Return products
+     *
+     * @return array
+     */
+    public function getProducts()
+    {
+        return $this->products;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
index ec83b427149d4d37f7e7d4cca75136074b0f59ec..8a6905704118bb1ffc5f41b43b14480870cc72b0 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute.xml
@@ -288,6 +288,6 @@
             <input></input>
         </search_weight>
     </fields>
-    <repository_class>Magento\Catalog\Test\Repository\CatalogAttributeEntity</repository_class>
-    <handler_interface>Magento\Catalog\Test\Handler\CatalogAttributeEntity\CatalogAttributeEntityInterface</handler_interface>
+    <repository_class>Magento\Catalog\Test\Repository\CatalogProductAttribute</repository_class>
+    <handler_interface>Magento\Catalog\Test\Handler\CatalogProductAttribute\CatalogAttributeEntityInterface</handler_interface>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute/Options.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute/Options.php
index b9be6d7cf2f8bfdab06bd6b1db2f703983fdd6ed..66bf16fdb748969609a87489209145e98a18b4ab 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute/Options.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductAttribute/Options.php
@@ -33,9 +33,24 @@ use Mtf\Fixture\FixtureInterface;
 class Options implements FixtureInterface
 {
     /**
-     * @constructor
-     * @param array $params
-     * @param array $data
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Constructor
+     *
+     * @param array $params [optional]
+     * @param array $data [optional]
      */
     public function __construct(array $params, array $data = [])
     {
@@ -60,7 +75,7 @@ class Options implements FixtureInterface
     /**
      * Return prepared data set
      *
-     * @param string|null $key
+     * @param string|null $key [optional]
      * @return mixed
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -97,9 +112,11 @@ class Options implements FixtureInterface
                 ]
             ],
         ];
+
         if (!isset($presets[$name])) {
             return null;
         }
+
         return $presets[$name];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
index 3bc3fb8d958328fbb2a8f60b6fc23c0762193eab..67590d6d8dc3cf08678141cc7f9795ed16ad152c 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.php
@@ -102,8 +102,10 @@ class CatalogProductSimple extends InjectableFixture
         'attribute_set_id' => ['dataSet' => 'default'],
         'price' => ['value' => 100.00],
         'weight' => 12.0000,
-        'qty' => 10,
-        'quantity_and_stock_status' => 'In Stock',
+        'quantity_and_stock_status' => [
+            'qty' => 10.0000,
+            'is_in_stock' => 'In Stock',
+        ],
     ];
 
     protected $category_ids = [
@@ -561,12 +563,6 @@ class CatalogProductSimple extends InjectableFixture
         'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId',
     ];
 
-    protected $qty = [
-        'attribute_code' => 'qty',
-        'input' => 'input',
-        'group' => 'product-details',
-    ];
-
     protected $custom_options = [
         'attribute_code' => 'custom_options',
         'backend_type' => 'virtual',
@@ -578,7 +574,8 @@ class CatalogProductSimple extends InjectableFixture
     protected $website_ids = [
         'attribute_code' => 'website_ids',
         'backend_type' => 'virtual',
-        'default_value' => 'Main Website',
+        'default_value' => ['Main Website'],
+        'group' => 'websites',
     ];
 
     public function getCategoryIds()
@@ -856,11 +853,6 @@ class CatalogProductSimple extends InjectableFixture
         return $this->getData('attribute_set_id');
     }
 
-    public function getQty()
-    {
-        return $this->getData('qty');
-    }
-
     public function getCustomOptions()
     {
         return $this->getData('custom_options');
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
index 2292b5ade4949fc2fc155b7ce75895266c93f14a..feccbc686956427730064ba45598084b355eea1f 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductSimple.xml
@@ -353,6 +353,7 @@
             <is_required>0</is_required>
             <default_value>Taxable Goods</default_value>
             <input>select</input>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\TaxClass</source>
             <group>product-details</group>
         </tax_class_id>
         <thumbnail>
@@ -427,13 +428,9 @@
         <attribute_set_id>
             <attribute_code>attribute_set_id</attribute_code>
             <backend_type>virtual</backend_type>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId</source>
             <group>product-details</group>
         </attribute_set_id>
-        <qty>
-            <attribute_code>qty</attribute_code>
-            <input>input</input>
-            <group>product-details</group>
-        </qty>
         <custom_options>
             <attribute_code>custom_options</attribute_code>
             <backend_type>virtual</backend_type>
@@ -446,6 +443,7 @@
             <attribute_code>website_ids</attribute_code>
             <backend_type>virtual</backend_type>
             <default_value>Main Website</default_value>
+            <group>websites</group>
         </website_ids>
     </fields>
     <data_set>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
index 9b6c364cd58425e6a326a6c66f1f06c75ec8a66b..9022128f7bca18a2c81451c8549009a8ab7cb096 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.php
@@ -82,6 +82,7 @@ class CatalogProductVirtual extends InjectableFixture
             $dataSet,
             $persist
         );
+
         if (!isset($this->data['url_key']) && isset($this->data['name'])) {
             $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-');
         }
@@ -96,11 +97,20 @@ class CatalogProductVirtual extends InjectableFixture
     ];
 
     protected $defaultDataSet = [
-        'name' => 'Test simple product %isolation%',
-        'sku' => 'test_simple_sku_%isolation%',
+        'name' => 'Test virtual product %isolation%',
+        'sku' => 'sku_test_virtual_product_%isolation%',
         'price' => ['value' => 100.00],
-        'weight' => 12.0000,
-        'qty' => 10
+        'quantity_and_stock_status' => [
+            'qty' => 10.0000,
+            'is_in_stock' => 'In Stock',
+        ],
+        'is_virtual' => 'Yes'
+    ];
+
+    protected $is_virtual = [
+        'attribute_code' => 'is_virtual',
+        'backend_type' => 'virtual',
+        'group' => 'product-details',
     ];
 
     protected $category_ids = [
@@ -554,12 +564,8 @@ class CatalogProductVirtual extends InjectableFixture
     protected $attribute_set_id = [
         'attribute_code' => 'attribute_set_id',
         'backend_type' => 'virtual',
-    ];
-
-    protected $qty = [
-        'attribute_code' => 'qty',
-        'input' => 'input',
         'group' => 'product-details',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId',
     ];
 
     protected $custom_options = [
@@ -570,11 +576,22 @@ class CatalogProductVirtual extends InjectableFixture
         'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
+    protected $website_ids = [
+        'attribute_code' => 'website_ids',
+        'backend_type' => 'virtual',
+        'default_value' => 'Main Website',
+    ];
+
     public function getCategoryIds()
     {
         return $this->getData('category_ids');
     }
 
+    public function getIsVirtual()
+    {
+        return $this->getData('is_virtual');
+    }
+
     public function getColor()
     {
         return $this->getData('color');
@@ -845,13 +862,13 @@ class CatalogProductVirtual extends InjectableFixture
         return $this->getData('attribute_set_id');
     }
 
-    public function getQty()
+    public function getCustomOptions()
     {
-        return $this->getData('qty');
+        return $this->getData('custom_options');
     }
 
-    public function getCustomOptions()
+    public function getWebsiteIds()
     {
-        return $this->getData('custom_options');
+        return $this->getData('website_ids');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
index 69fd4f87cc83fde51d21777a06582d2e73a6d770..fee9f0037b27f1d9aa2e994fa81d94d76fb24238 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Fixture/CatalogProductVirtual.xml
@@ -420,6 +420,10 @@
             <attribute_code>id</attribute_code>
             <backend_type>virtual</backend_type>
         </id>
+        <is_virtual>
+            <attribute_code>is_virtual</attribute_code>
+            <backend_type>virtual</backend_type>
+        </is_virtual>
         <type_id>
             <attribute_code>type_id</attribute_code>
             <backend_type>virtual</backend_type>
@@ -427,12 +431,9 @@
         <attribute_set_id>
             <attribute_code>attribute_set_id</attribute_code>
             <backend_type>virtual</backend_type>
-        </attribute_set_id>
-        <qty>
-            <attribute_code>qty</attribute_code>
-            <input>input</input>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId</source>
             <group>product-details</group>
-        </qty>
+        </attribute_set_id>
         <custom_options>
             <attribute_code>custom_options</attribute_code>
             <backend_type>virtual</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
index 88e86d5ea38bd06c0de8e63219ea74df72646dca..f2d5662eb7f4d4ae781c9f2c8aa8d1e7ada633ec 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductAttribute/Curl.php
@@ -30,7 +30,6 @@ use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Handler\Curl as AbstractCurl;
 use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
-use Magento\Backend\Test\Handler\Extractor;
 
 /**
  * Class Curl
@@ -65,7 +64,7 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
     /**
      * Post request for creating Product Attribute
      *
-     * @param FixtureInterface $fixture
+     * @param FixtureInterface|null $fixture [optional]
      * @return array
      * @throws \Exception
      */
@@ -87,9 +86,9 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
             unset($data['options']);
         }
 
-        $url = $_ENV['app_backend_url'] . 'catalog/product_attribute/save/';
+        $url = $_ENV['app_backend_url'] . 'catalog/product_attribute/save/back/edit';
         $curl = new BackendDecorator(new CurlTransport(), new Config);
-        $curl->write(CurlInterface::POST, $url, '1.0', array(), $data);
+        $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
         $response = $curl->read();
         $curl->close();
 
@@ -97,11 +96,22 @@ class Curl extends AbstractCurl implements CatalogProductAttributeInterface
             throw new \Exception("Product Attribute creating by curl handler was not successful!");
         }
 
-        $url = 'catalog/product_attribute/index/filter/';
-        $url .= base64_encode('frontend_label=' . $data['frontend_label'][0]);
-        $regExpPattern = '`<tr.*?http.*?attribute_id\/(\d*?)\/`';
-        $extractor = new Extractor($url, $regExpPattern);
+        $resultData = [];
+        $matches = [];
+        preg_match('#attribute_id[^>]+value="(\d+)"#', $response, $matches);
+        $resultData['attribute_id'] = $matches[1];
 
-        return ['attribute_id' => $extractor->getData()[1]];
+        $matches = [];
+        preg_match_all('#"id":"(\d+)"#Umi', $response, $matches);
+
+        if ($fixture->hasData('options')) {
+            $optionsData = $fixture->getData()['options'];
+            foreach ($matches[1] as $key => $optionId) {
+                $optionsData[$key]['id'] = $optionId;
+            }
+            $resultData['options'] = $optionsData;
+        }
+
+        return $resultData;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
index 17a11a39c6018e1b8c800fdf4fb077ee47448d93..b7152dd13a39a1246b028a36205834596f2e1fcc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/CatalogProductSimpleInterface.php
@@ -21,6 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Catalog\Test\Handler\CatalogProductSimple;
 
 use Mtf\Handler\HandlerInterface;
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
index f1f298234fbd9d38473c7f10145ea82697e4a783..0c754bc08144e6e08a2317cf12ae8f9ab31077f5 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductSimple/Curl.php
@@ -26,7 +26,6 @@ namespace Magento\Catalog\Test\Handler\CatalogProductSimple;
 
 use Mtf\System\Config;
 use Mtf\Fixture\FixtureInterface;
-use Mtf\Fixture\InjectableFixture;
 use Mtf\Util\Protocol\CurlInterface;
 use Mtf\Util\Protocol\CurlTransport;
 use Mtf\Handler\Curl as AbstractCurl;
@@ -44,6 +43,19 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
      * @var array
      */
     protected $mappingData = [
+        'links_purchased_separately' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
+        'is_shareable' => [
+            'Yes' => 1,
+            'No' => 0,
+            'Use config' => 2
+        ],
+        'required' => [
+            'Yes' => 1,
+            'No' => 0
+        ],
         'manage_stock' => [
             'Yes' => 1,
             'No' => 0
@@ -51,15 +63,15 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         'is_virtual' => [
             'Yes' => 1
         ],
-        'inventory_manage_stock' => [
+        'use_config_enable_qty_increments' => [
             'Yes' => 1,
             'No' => 0
         ],
-        'is_in_stock' => [
-            'In Stock' => 1,
-            'Out of Stock' => 0
+        'use_config_qty_increments' => [
+            'Yes' => 1,
+            'No' => 0
         ],
-        'quantity_and_stock_status' => [
+        'is_in_stock' => [
             'In Stock' => 1,
             'Out of Stock' => 0
         ],
@@ -75,16 +87,13 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         'status' => [
             'Product offline' => 2,
             'Product online' => 1
-        ],
-        'attribute_set_id' => [
-            'Default' => 4
         ]
     ];
 
     /**
      * Post request for creating simple product
      *
-     * @param FixtureInterface $fixture [optional]
+     * @param FixtureInterface|null $fixture [optional]
      * @return array
      * @throws \Exception
      *
@@ -124,29 +133,11 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         return (int)$matches[1];
     }
 
-    /**
-     * Remove items from a null
-     *
-     * @param array $data
-     * @return array
-     */
-    protected function filter(array $data)
-    {
-        foreach ($data as $key => $value) {
-            if ($value === null) {
-                unset($data[$key]);
-            } elseif (is_array($data[$key])) {
-                $data[$key] = $this->filter($data[$key]);
-            }
-        }
-        return $data;
-    }
-
     /**
      * Prepare POST data for creating product request
      *
      * @param FixtureInterface $fixture
-     * @param string|null $prefix
+     * @param string|null $prefix [optional]
      * @return array
      *
      * @SuppressWarnings(PHPMD.CyclomaticComplexity)
@@ -155,7 +146,6 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
     protected function prepareData(FixtureInterface $fixture, $prefix = null)
     {
         $fields = $this->replaceMappingData($fixture->getData());
-        $fields = $this->prepareStockData($fields);
         // Getting Tax class id
         if ($fixture->hasData('tax_class_id')) {
             $taxClassId = $fixture->getDataFieldConfig('tax_class_id')['source']->getTaxClass()->getId();
@@ -189,9 +179,9 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
             $fields['attribute_set_id'] = $attributeSetId;
         }
 
-        $data = $prefix ? [$prefix => $fields] : $fields;
+        $fields = $this->prepareStockData($fields);
 
-        return $data;
+        return $prefix ? [$prefix => $fields] : $fields;
     }
 
     /**
@@ -199,31 +189,56 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
      *
      * @param array $fields
      * @return array
+     *
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     protected function prepareStockData(array $fields)
     {
-        $fields['stock_data']['manage_stock'] = 0;
+        if (isset($fields['quantity_and_stock_status']) && !is_array($fields['quantity_and_stock_status'])) {
+            $fields['quantity_and_stock_status'] = [
+                'qty' => $fields['qty'],
+                'is_in_stock' => $fields['quantity_and_stock_status']
+            ];
+        }
 
         if (!isset($fields['stock_data']['is_in_stock'])) {
-            $fields['stock_data']['is_in_stock'] = isset($fields['quantity_and_stock_status'])
-                ? $fields['quantity_and_stock_status']
+            $fields['stock_data']['is_in_stock'] = isset($fields['quantity_and_stock_status']['is_in_stock'])
+                ? $fields['quantity_and_stock_status']['is_in_stock']
                 : (isset($fields['inventory_manage_stock']) ? $fields['inventory_manage_stock'] : null);
         }
         if (!isset($fields['stock_data']['qty'])) {
-            $fields['stock_data']['qty'] = isset($fields['qty']) ? $fields['qty'] : null;
-        }
-        if (!empty($fields['stock_data']['qty'])) {
-            $fields['stock_data']['manage_stock'] = 1;
+            $fields['stock_data']['qty'] = isset($fields['quantity_and_stock_status']['qty'])
+                ? $fields['quantity_and_stock_status']['qty']
+                : null;
         }
 
-        $fields['quantity_and_stock_status'] = [
-            'qty' => $fields['stock_data']['qty'],
-            'is_in_stock' => $fields['stock_data']['is_in_stock']
-        ];
+        if (!isset($fields['stock_data']['manage_stock'])) {
+            $fields['stock_data']['manage_stock'] = (int)(!empty($fields['stock_data']['qty'])
+                || !empty($fields['stock_data']['is_in_stock']));
+        }
 
         return $this->filter($fields);
     }
 
+    /**
+     * Remove items from a null
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function filter(array $data)
+    {
+        foreach ($data as $key => $value) {
+            if ($value === null) {
+                unset($data[$key]);
+            } elseif (is_array($data[$key])) {
+                $data[$key] = $this->filter($data[$key]);
+            }
+        }
+        return $data;
+    }
+
     /**
      * Create product via curl
      *
@@ -245,21 +260,8 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
             throw new \Exception("Product creation by curl handler was not successful! Response: $response");
         }
         preg_match("~Location: [^\s]*\/id\/(\d+)~", $response, $matches);
-        return isset($matches[1]) ? $matches[1] : null;
-    }
 
-    /**
-     * Retrieve field value or return null if value does not exist
-     *
-     * @param array $values
-     * @return null|mixed
-     */
-    protected function getValue($values)
-    {
-        if (!isset($values['value'])) {
-            return null;
-        }
-        return isset($values['input_value']) ? $values['input_value'] : $values['value'];
+        return isset($matches[1]) ? $matches[1] : null;
     }
 
     /**
@@ -275,6 +277,7 @@ class Curl extends AbstractCurl implements CatalogProductSimpleInterface
         foreach ($requestParams as $key => $value) {
             $params .= $key . '/' . $value . '/';
         }
+
         return $_ENV['app_backend_url'] . 'catalog/product/save/' . $params . 'popup/1/back/edit';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/CatalogProductVirtualInterface.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/CatalogProductVirtualInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..cc4281f5af0df781cbe055d79db7bc7ac23f24de
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/CatalogProductVirtualInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Handler\CatalogProductVirtual;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CatalogProductVirtualInterface
+ */
+interface CatalogProductVirtualInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/Curl.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..121b83d8de9f4f7a2dff768445fde2d0d00e20ee
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Handler/CatalogProductVirtual/Curl.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Handler\CatalogProductVirtual;
+
+use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
+
+/**
+ * Class Curl
+ * Create new virtual product via curl
+ */
+class Curl extends ProductCurl implements CatalogProductVirtualInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php
deleted file mode 100644
index a6e377dee180bb8ff9052050bdc77f49c4f4437d..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductReview.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Test\Page\Product;
-
-use Mtf\Page\Page;
-use Mtf\Factory\Factory;
-
-/**
- * Backend product review page
- *
- */
-class CatalogProductReview extends Page
-{
-    /**
-     * URL for catalog product review
-     */
-    const MCA = 'review/product';
-
-    /**
-     * Review grid selector
-     *
-     * @var string
-     */
-    protected $gridSelector = '#reviwGrid';
-
-    /**
-     * Edit form review selector
-     *
-     * @var string
-     */
-    protected $editFormSelector = '#anchor-content';
-
-    /**
-     * Messages selector
-     *
-     * @var string
-     */
-    protected $messageWrapperSelector = '#messages';
-
-    /**
-     * {@inheritdoc}
-     */
-    protected function _init()
-    {
-        $this->_url = $_ENV['app_backend_url'] . self::MCA;
-    }
-
-    /**
-     * Get product reviews grid
-     *
-     * @return \Magento\Review\Test\Block\Adminhtml\Grid
-     */
-    public function getGridBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoReviewAdminhtmlGrid($this->_browser->find($this->gridSelector));
-    }
-
-    /**
-     * Get review edit form
-     *
-     * @return \Magento\Review\Test\Block\Adminhtml\Edit
-     */
-    public function getEditForm()
-    {
-        return Factory::getBlockFactory()->getMagentoReviewAdminhtmlEdit(
-            $this->_browser->find($this->editFormSelector)
-        );
-    }
-
-    /**
-     * Get messages block
-     *
-     * @return \Magento\Core\Test\Block\Messages
-     */
-    public function getMessagesBlock()
-    {
-        return Factory::getBlockFactory()->getMagentoCoreMessages($this->_browser->find($this->messageWrapperSelector));
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/Page/Product/CatalogProductView.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
index 9445bc407857fd0dbd352c9a47f08b321715c33b..00e5f45899fa1940fbbf5adb30152e219a764537 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogCategory.php
@@ -49,7 +49,7 @@ class CatalogCategory extends AbstractRepository
 
         $this->_data['default_subcategory'] = [
             'name' => 'DefaultSubcategory%isolation%',
-            'url_key' => 'DefaultSubcategory%isolation%',
+            'url_key' => 'default-subcategory-%isolation%',
             'parent_id' => ['dataSet' => 'default_category'],
             'is_active' => 'Yes',
             'include_in_menu' => 'Yes',
@@ -57,7 +57,7 @@ class CatalogCategory extends AbstractRepository
 
         $this->_data['root_category'] = [
             'name' => 'RootCategory%isolation%',
-            'url_key' => 'RootCategory%isolation%',
+            'url_key' => 'root-category-%isolation%',
             'parent_id' => 1,
             'is_active' => 'Yes',
             'include_in_menu' => 'Yes'
@@ -65,7 +65,7 @@ class CatalogCategory extends AbstractRepository
 
         $this->_data['root_subcategory'] = [
             'name' => 'RootSubCategory%isolation%',
-            'url_key' => 'RootSubCategory%isolation%',
+            'url_key' => 'root-sub-category-%isolation%',
             'parent_id' => ['dataSet' => 'root_category'],
             'is_active' => 'Yes',
             'include_in_menu' => 'Yes'
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
index 44698ac538f667c071d3e89411acc0a81ac6ca1e..fd546ebee5d46f198345ad0893f35a68beb393cc 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductAttribute.php
@@ -35,8 +35,8 @@ class CatalogProductAttribute extends AbstractRepository
     /**
      * Construct
      *
-     * @param array $defaultConfig
-     * @param array $defaultData
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
@@ -55,20 +55,20 @@ class CatalogProductAttribute extends AbstractRepository
             'frontend_input' => 'Dropdown',
             'is_required' => 'No',
             'options' => [
-                1 => [
+                [
                     'is_default' => 'Yes',
                     'admin' => 'black',
-                    'view' => 'option_0',
+                    'view' => 'option_0_%isolation%',
                 ],
-                2 => [
+                [
                     'is_default' => 'No',
                     'admin' => 'white',
-                    'view' => 'option_1',
+                    'view' => 'option_1_%isolation%',
                 ],
-                3 => [
+                [
                     'is_default' => 'No',
                     'admin' => 'green',
-                    'view' => 'option_2',
+                    'view' => 'option_2_%isolation%',
                 ]
             ]
         ];
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
index feddf6acf48a5c9ea9fa8f23ef5dafbf4e376e58..c908338c2edbe89daf7d33ec13a27f13795f63c3 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductSimple.php
@@ -33,8 +33,10 @@ use Mtf\Repository\AbstractRepository;
 class CatalogProductSimple extends AbstractRepository
 {
     /**
-     * @param array $defaultConfig
-     * @param array $defaultData
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
@@ -46,17 +48,24 @@ class CatalogProductSimple extends AbstractRepository
             'name' => 'Simple Product %isolation%',
             'sku' => 'sku_simple_product_%isolation%',
             'weight' => 1,
-            'quantity_and_stock_status' => 'In Stock',
-            'qty' => 25,
-            'price' => ['value' => 560, 'preset' => '-'],
+            'quantity_and_stock_status' => [
+                'qty' => 25.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'price' => ['value' => 560.00, 'preset' => '-'],
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
             'website_ids' => ['Main Website'],
         ];
 
         $this->_data['100_dollar_product'] = [
             'sku' => '100_dollar_product%isolation%',
             'name' => '100_dollar_product%isolation%',
+            'type_id' => 'simple',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'attribute_set_id' => ['dataSet' => 'default'],
-            'quantity_and_stock_status' => 'In Stock',
             'price' => ['value' => 100, 'preset' => '-'],
             'website_ids' => ['Main Website'],
         ];
@@ -64,10 +73,13 @@ class CatalogProductSimple extends AbstractRepository
         $this->_data['40_dollar_product'] = [
             'sku' => '40_dollar_product',
             'name' => '40_dollar_product',
+            'type_id' => 'simple',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'attribute_set_id' => ['dataSet' => 'default'],
-            'quantity_and_stock_status' => 'In Stock',
             'price' => ['value' => 40, 'preset' => '-'],
-            'id' => '2',
             'mtf_dataset_name' => '40_dollar_product',
             'website_ids' => ['Main Website'],
         ];
@@ -76,9 +88,12 @@ class CatalogProductSimple extends AbstractRepository
             'sku' => 'MAGETWO-23036',
             'name' => 'simple_with_category',
             'attribute_set_id' => ['dataSet' => 'default'],
-            'quantity_and_stock_status' => 'In Stock',
+            'type_id' => 'simple',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'price' => ['value' => 100, 'preset' => 'MAGETWO-23036'],
-            'id' => '3',
             'category_ids' => ['presets' => 'default'],
             'mtf_dataset_name' => 'simple_with_category',
             'website_ids' => ['Main Website'],
@@ -87,6 +102,10 @@ class CatalogProductSimple extends AbstractRepository
         $this->_data['product_with_category'] = [
             'sku' => 'simple_product_with_category_%isolation%',
             'name' => 'Simple product with category %isolation%',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'attribute_set_id' => ['dataSet' => 'default'],
             'price' => ['value' => 100, 'preset' => ''],
             'category_ids' => ['presets' => 'default_subcategory'],
@@ -96,7 +115,11 @@ class CatalogProductSimple extends AbstractRepository
 
         $this->_data['simple_for_salesrule_1'] = [
             'attribute_set_id' => ['dataSet' => 'default'],
-            'quantity_and_stock_status' => 'In Stock',
+            'type_id' => 'simple',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'name' => 'Simple Product %isolation%',
             'sku' => 'sku_simple_product_%isolation%',
             'price' => ['value' => 100, 'preset' => ''],
@@ -131,21 +154,13 @@ class CatalogProductSimple extends AbstractRepository
             'price' => ['value' => 100.00, 'preset' => '-'],
             'tax_class_id' => ['dataSet' => 'None'],
             'quantity_and_stock_status' => [
-                'qty' => 666,
-                'is_in_stock' => 'Yes',
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
             ],
             'weight' => 1.0000,
             'description' => '<p>dfj_full</p>',
             'status' => 'Product online',
-            'website_ids' => [
-                0 => 'Main Website',
-            ],
-            'stock_data' => [
-                'manage_stock' => 'Yes',
-                'original_inventory_qty' => 666,
-                'qty' => 666.0000,
-                'is_in_stock' => 'In Stock',
-            ],
+            'website_ids' => ['Main Website'],
             'visibility' => 'Catalog, Search',
         ];
 
@@ -162,15 +177,7 @@ class CatalogProductSimple extends AbstractRepository
             'description' => '<p>adc_Full</p>',
             'status' => 'Product online',
             'short_description' => '<p>abc_short</p>',
-            'website_ids' => [
-                0 => 'Main Website',
-            ],
-            'stock_data' => [
-                'manage_stock' => 'Yes',
-                'original_inventory_qty' => 666,
-                'qty' => 666.0000,
-                'is_in_stock' => 'Yes',
-            ],
+            'website_ids' => ['Main Website'],
             'visibility' => 'Catalog, Search',
         ];
 
@@ -178,8 +185,11 @@ class CatalogProductSimple extends AbstractRepository
             'sku' => '100_dollar_product%isolation%',
             'name' => '100_dollar_product%isolation%',
             'attribute_set_id' => ['dataSet' => 'default'],
-            'quantity_and_stock_status' => 'In Stock',
-            'qty' => 25,
+            'type_id' => 'simple',
+            'quantity_and_stock_status' => [
+                'qty' => 25.0000,
+                'is_in_stock' => 'In Stock',
+            ],
             'price' => ['value' => 100, 'preset' => '-'],
             'website_ids' => ['Main Website'],
         ];
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php
new file mode 100644
index 0000000000000000000000000000000000000000..db7579fae10b2944e74b8724c614d5faa37653f2
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/Repository/CatalogProductVirtual.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class CatalogProductVirtual
+ * Data for creation Catalog Product Virtual
+ */
+class CatalogProductVirtual extends AbstractRepository
+{
+    /**
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['default'] = [
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'status' => 'Product online',
+            'website_ids' => ['Main Website'],
+            'is_virtual' => 'Yes',
+            'url_key' => 'virtual-product%isolation%',
+            'visibility' => 'Catalog, Search',
+            'attribute_set_id' => ['dataSet' => 'default'],
+            'name' => 'Virtual product %isolation%',
+            'sku' => 'sku_virtual_product_%isolation%',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'price' => ['value' => 10.00, 'preset' => '-']
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..989eaee4492a3ae69be32d607fab60918b96fb4c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest.php
@@ -0,0 +1,90 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Test\TestCase\Category;
+
+use Mtf\TestCase\Injectable;
+use Magento\Catalog\Test\Fixture\CatalogCategory;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryEdit;
+use Magento\Catalog\Test\Page\Adminhtml\CatalogCategoryIndex;
+
+/**
+ * Test Creation for CreateCategoryEntity
+ *
+ * Test Flow:
+ * 1. Login as admin
+ * 2. Navigate to the Products>Inventory>Categories
+ * 3. Click on 'Add Category' button
+ * 4. Fill out all data according to data set
+ * 5. Save category
+ * 6. Verify created category
+ *
+ * @group Category_Management_(MX)
+ * @ZephyrId MAGETWO-23411
+ */
+class CreateCategoryEntityTest extends Injectable
+{
+    /**
+     * Catalog category index page
+     *
+     * @var CatalogCategoryIndex
+     */
+    protected $catalogCategoryIndex;
+
+    /**
+     * Catalog category edit page
+     *
+     * @var CatalogCategoryEdit
+     */
+    protected $catalogCategoryEdit;
+
+    /**
+     * Inject pages
+     *
+     * @param CatalogCategoryIndex $catalogCategoryIndex
+     * @param CatalogCategoryEdit $catalogCategoryEdit
+     * @return void
+     */
+    public function __inject(CatalogCategoryIndex $catalogCategoryIndex, CatalogCategoryEdit $catalogCategoryEdit)
+    {
+        $this->catalogCategoryIndex = $catalogCategoryIndex;
+        $this->catalogCategoryEdit = $catalogCategoryEdit;
+    }
+
+    /**
+     * Create category
+     *
+     * @param CatalogCategory $category
+     * @param string $addCategory
+     * @return void
+     */
+    public function test(CatalogCategory $category, $addCategory)
+    {
+        $this->catalogCategoryIndex->open();
+        $this->catalogCategoryIndex->getTreeCategories()->selectCategory($category, false);
+        $this->catalogCategoryIndex->getTreeCategories()->$addCategory();
+        $this->catalogCategoryEdit->getEditForm()->fill($category);
+        $this->catalogCategoryEdit->getFormPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv
new file mode 100644
index 0000000000000000000000000000000000000000..d98cdd09e2a00a85ad248b4b02459464ab949c14
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Category/CreateCategoryEntityTest/test.csv
@@ -0,0 +1,8 @@
+"addCategory";"category/data/parent_id/dataSet";"category/data/name";"category/data/url_key";"category/data/is_active";"category/data/description";"category/data/meta_title";"category/data/include_in_menu";"category/data/display_mode";"category/data/landing_page";"category/data/is_anchor";"category/data/available_product_listing_config";"category/data/available_sort_by/sort_0";"category/data/available_sort_by/sort_1";"category/data/available_sort_by/sort_2";"category/data/default_product_listing_config";"category/data/default_sort_by";"category/data/use_config_price_range";"category/data/layered_navigation_price_step";"category/data/category_products_data/preset";"category/data/category_products/dataSet";"constraint"
+"addRootCategory";"1";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory Required ";"-";"-";"-";"-";"-";"No";"Position";"Name";"Price";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
+"addRootCategory";"1";"RootCategory%isolation%";"RootCategory%isolation%";"Yes";"RootCategory All Fields ";"RootCategory Page Title";"Yes";"Static block and products";"Footer Links";"Yes";"No";"Position";"Name";"Price";"No";"Name";"No";"50";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
+"addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Subcategory Required";"-";"-";"-";"-";"-";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage"
+"addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Subcategory For Anchor Subcategory";"-";"Yes";"-";"-";"No";"Yes";"-";"-";"-";"Yes";"-";"Yes";"-";"default";"catalogProductSimple::default,catalogProductSimple::default";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage, assertCategoryForAssignedProducts"
+"addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Anchor Subcategory All Fields";"Subcategory Page Title";"Yes";"Products only";"Catalog Events Lister";"Yes";"No";"Position";"Name";"Price";"No";"Price";"No";"50";"default";"catalogProductSimple::default,catalogProductSimple::default";"assertCategorySaveMessage, assertCategoryForm, assertCategoryPage, assertCategoryForAssignedProducts"
+"addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Not active category";"-";"Yes";"-";"-";"-";"Yes";"-";"-";"-";"Yes";"-";"Yes";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
+"addSubcategory";"default_category";"Subcategory%isolation%";"Subcategory%isolation%";"Yes";"Not included in menu";"-";"No";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"-";"assertCategorySaveMessage, assertCategoryForm"
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv
index 2e81c0aad84ba07a30381a02839c9f48e53c2433..de3705644ba17a842ade495d66b0c068da297133 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/CreateVirtualProductEntityTest/testCreate.csv
@@ -1,4 +1,4 @@
-"product/data/name";"product/data/sku";"product/data/price/value";"product/data/tax_class_id/dataSet";"product/data/qty";"product/data/is_virtual";"product/data/category";"product/data/group_price/preset";"product/data/price/preset";"product/data/tier_price/preset";"product/data/inventory_manage_stock";"product/data/quantity_and_stock_status";"product/data/custom_options/preset";"product/data/visibility";"constraint"
+"product/data/name";"product/data/sku";"product/data/price/value";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/is_virtual";"product/data/category";"product/data/group_price/preset";"product/data/price/preset";"product/data/tier_price/preset";"product/data/inventory_manage_stock";"product/data/quantity_and_stock_status/is_in_stock";"product/data/custom_options/preset";"product/data/visibility";"constraint"
 "VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"-";"-";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"assertProductSaveMessage, assertProductInGrid"
 "VirtualProduct %isolation%";"virtual_sku_%isolation%";"10";"None";"999";"Yes";"category_%isolation%";"-";"-";"MAGETWO-23002";"Yes";"In Stock";"-";"Catalog, Search";"assertProductSaveMessage, assertProductVisibleInCategory, assertProductForm, assertProductSearchableBySku"
 "VirtualProduct %isolation%";"-";"10";"Taxable Goods";"999";"Yes";"-";"-";"MAGETWO-23030";"-";"-";"Out of Stock";"-";"Search";"assertProductSaveMessage, assertProductForm, assertProductSkuAutoGenerated, assertProductSearchableBySku"
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv
index fb266402aac0072193f70fb807e64e181090b154..26fb9198a5ccf49d548a1cd968e7400879d3f425 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/TestCase/Product/UpdateSimpleProductEntityTest/testUpdate.csv
@@ -1,4 +1,4 @@
-"product/data/name";"product/data/sku";"product/data/price/value";"product/data/qty";"product/data/quantity_and_stock_status";"product/data/url_key";"product/data/weight";"product/data/visibility";"product/data/status";"constraint"
+"product/data/name";"product/data/sku";"product/data/price/value";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/url_key";"product/data/weight";"product/data/visibility";"product/data/status";"constraint"
 "Test simple product %isolation%";"test_simple_product_%isolation%";"245.00";"200.0000";"-";"test-simple-product-%isolation%";"120.0000";"Catalog, Search";"-";"assertProductSaveMessage, assertProductForm, assertProductInStock, assertProductVisibleInCategory, assertProductPage"
 "Test simple product %isolation%";"test_simple_product_%isolation%";"325.00";"123.0000";"-";"test-simple-product-%isolation%";"129.0000";"Not Visible Individually";"-";"assertProductSaveMessage, assertProductForm, assertProductIsNotDisplayingOnFrontend"
 "Test simple product %isolation%";"test_simple_product_%isolation%";"325.01";"125.0000";"-";"test-simple-product-%isolation%";"25.0000";"Catalog";"-";"assertProductSaveMessage, assertProductInStock, assertProductForm, assertProductSearchableBySku, assertProductVisibleInCategory, assertProductPage"
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
index 91e0087de29d1a723c2096acc5ef7b6cc84b3e8a..8e2e4769052aacfbc10e39854ca75e29b11a4c63 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/curl/di.xml
@@ -28,4 +28,5 @@
     <preference for="Magento\Catalog\Test\Handler\CatalogProductAttribute\CatalogProductAttributeInterface" type="\Magento\Catalog\Test\Handler\CatalogProductAttribute\Curl" />
     <preference for="Magento\Catalog\Test\Handler\CatalogAttributeSet\CatalogAttributeSetInterface" type="\Magento\Catalog\Test\Handler\CatalogAttributeSet\Curl" />
     <preference for="Magento\Catalog\Test\Handler\CatalogCategory\CatalogCategoryInterface" type="\Magento\Catalog\Test\Handler\CatalogCategory\Curl" />
+    <preference for="Magento\Catalog\Test\Handler\CatalogProductVirtual\CatalogProductVirtualInterface" type="\Magento\Catalog\Test\Handler\CatalogProductVirtual\Curl" />
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
index 5293569e798ff4a72f60587baf4081813ca42d03..e3c25a122c8d7b76398b5f690509065a17a70239 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/constraint.xml
@@ -27,104 +27,104 @@
     <assertProductInGrid module="Magento_Catalog">
         <severeness>high</severeness>
         <require>
-            <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductInGrid>
     <assertProductSaveMessage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit" />
+            <productPage class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductEdit"/>
         </require>
     </assertProductSaveMessage>
     <assertProductOutOfStock module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductOutOfStock>
     <assertProductInStock module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductInStock>
     <assertProductVisibleInCategory module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <category class="Magento\Catalog\Test\Fixture\CatalogCategory" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductVisibleInCategory>
     <assertProductSearchableBySku module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductSearchableBySku>
     <assertProductInCategory module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <product class="Mtf\Fixture\FixtureInterface" />
-            <category class="Magento\Catalog\Test\Fixture\CatalogCategory" />
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/>
         </require>
     </assertProductInCategory>
     <assertProductInCart module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
-            <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
+            <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart"/>
         </require>
     </assertProductInCart>
     <assertProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductPage>
     <assertGroupedPriceOnProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertGroupedPriceOnProductPage>
     <assertSpecialPriceOnProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertSpecialPriceOnProductPage>
     <assertTierPriceOnProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertTierPriceOnProductPage>
     <assertCustomOptionsOnProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertCustomOptionsOnProductPage>
     <assertProductForm module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductForm>
     <assertAddToCartButtonAbsent module="Magento_Catalog">
@@ -134,34 +134,34 @@
         <severeness>low</severeness>
     </assertAddToCartButtonPresent>
     <assertProductIsNotDisplayingOnFrontend module="Magento_Catalog">
-        <severeness>low</severeness>
+        <severeness>high</severeness>
         <require>
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <product class="Mtf\Fixture\FixtureInterface" />
-            <category class="Magento\Catalog\Test\Fixture\CatalogCategory" />
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult" />
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
+            <category class="Magento\Catalog\Test\Fixture\CatalogCategory"/>
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <catalogSearchResult class="Magento\CatalogSearch\Test\Page\CatalogsearchResult"/>
         </require>
     </assertProductIsNotDisplayingOnFrontend>
     <assertProductSkuAutoGenerated module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <productGrid class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductIndex"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertProductSkuAutoGenerated>
     <assertGroupedPriceOnProductPage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <product class="Mtf\Fixture\FixtureInterface" />
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <product class="Mtf\Fixture\FixtureInterface"/>
         </require>
     </assertGroupedPriceOnProductPage>
     <assertProductAttributeSaveMessage module="Magento_Catalog">
         <severeness>high</severeness>
         <require>
-            <attributeIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex" />
+            <attributeIndex class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeIndex"/>
         </require>
     </assertProductAttributeSaveMessage>
     <assertProductAttributeInGrid module="Magento_Catalog">
@@ -225,12 +225,12 @@
     <assertCrossSellsProductsSection module="Magento_Catalog">
         <severeness>middle</severeness>
         <require>
-            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
-            <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart" />
+            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
+            <checkoutCart class="Magento\Checkout\Test\Page\CheckoutCart"/>
         </require>
     </assertCrossSellsProductsSection>
     <assertProductAttributeSuccessDeleteMessage module="Magento_Catalog">
@@ -242,11 +242,11 @@
     <assertRelatedProductsSection module="Magento_Catalog">
         <severeness>middle</severeness>
         <require>
-            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
         </require>
     </assertRelatedProductsSection>
     <assertProductAttributeAbsenceInGrid module="Magento_Catalog">
@@ -258,11 +258,11 @@
     <assertUpSellsProductsSection module="Magento_Catalog">
         <severeness>middle</severeness>
         <require>
-            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
-            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
-            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView" />
-            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView" />
+            <product1 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <product2 class="Magento\Catalog\Test\Fixture\CatalogProductSimple"/>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex"/>
+            <catalogCategoryView class="Magento\Catalog\Test\Page\Category\CatalogCategoryView"/>
+            <catalogProductView class="Magento\Catalog\Test\Page\Product\CatalogProductView"/>
         </require>
     </assertUpSellsProductsSection>
     <assertProductAttributeAbsenceInSearchOnProductForm module="Magento_Catalog">
@@ -280,6 +280,15 @@
     <assertCategoryPage module="Magento_Catalog">
         <severeness>low</severeness>
     </assertCategoryPage>
+    <assertCategoryForAssignedProducts module="Magento_Catalog">
+        <severeness>low</severeness>
+    </assertCategoryForAssignedProducts>
+    <assertCategoryIsNotActive module="Magento_Catalog">
+        <severeness>low</severeness>
+    </assertCategoryIsNotActive>
+    <assertCategoryIsNotIncludeInMenu module="Magento_Catalog">
+        <severeness>low</severeness>
+    </assertCategoryIsNotIncludeInMenu>
     <assertCategorySuccessDeleteMessage module="Magento_Catalog">
         <severeness>low</severeness>
         <require>
@@ -329,7 +338,13 @@
     <assertAbsenceDeleteAttributeButton module="Magento_Catalog">
         <severeness>high</severeness>
         <require>
-            <attributeNew class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeNew" />
+            <attributeNew class="Magento\Catalog\Test\Page\Adminhtml\CatalogProductAttributeNew"/>
         </require>
     </assertAbsenceDeleteAttributeButton>
+    <assertProductSuccessDeleteMessage module="Magento_Catalog">
+        <severeness>low</severeness>
+    </assertProductSuccessDeleteMessage>
+    <assertProductNotInGrid module="Magento_Catalog">
+        <severeness>low</severeness>
+    </assertProductNotInGrid>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
index b6320f265bec6f666654ca88e27e4469734bb04b..e9a13691255236a1840bdf51410a1cf23b3e581b 100644
--- a/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/Catalog/Test/etc/global/fixture.xml
@@ -43,10 +43,6 @@
                 <attribute_code>attribute_set_id</attribute_code>
                 <backend_type>virtual</backend_type>
             </attribute_set_id>
-            <qty>
-                <attribute_code>qty</attribute_code>
-                <input>input</input>
-            </qty>
         </fields>
         <data_set>
             <sku />
@@ -192,10 +188,6 @@
                 <attribute_code>attribute_set_id</attribute_code>
                 <backend_type>virtual</backend_type>
             </attribute_set_id>
-            <qty>
-                <attribute_code>qty</attribute_code>
-                <input>input</input>
-            </qty>
         </fields>
         <data_set>
             <sku />
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Advanced/Form.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Advanced/Form.php
index 2582fb7a08435da7b0bfcf4d0d230ddcd6463aa6..b714d39bc68a303dadea98db41a02118a2bbe4f5 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Advanced/Form.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Block/Advanced/Form.php
@@ -69,8 +69,10 @@ class Form extends ParentForm
     {
         // Prepare price data
         $data = $fixture->getData();
-        $data = array_merge($data, $data['price']);
-        unset($data['price']);
+        if (isset($data['price'])) {
+            $data = array_merge($data, $data['price']);
+            unset($data['price']);
+        }
 
         // Mapping
         $mapping = $this->dataMapping($data);
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb4b1d9a82254316d0639d779fbc55e4fd3284f0
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/Constraint/AssertCatalogSearchResult.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogSearch\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\CatalogSearch\Test\Page\AdvancedResult;
+use Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery;
+
+/**
+ * Class AssertCatalogSearchResult
+ */
+class AssertCatalogSearchResult extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that result page contains all products, according to search request, from fixture
+     *
+     * @param array $products
+     * @param AdvancedResult $resultPage
+     * @return void
+     */
+    public function processAssert(array $products, AdvancedResult $resultPage)
+    {
+        $errors = [];
+        foreach ($products as $product) {
+            $name = $product->getName();
+            $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($name);
+            while (!$isProductVisible && $resultPage->getToolbar()->nextPage()) {
+                $isProductVisible = $resultPage->getListProductBlock()->isProductVisible($name);
+            }
+
+            if ($isProductVisible === false) {
+                $errors[] = '- ' . $name;
+            }
+        }
+
+        \PHPUnit_Framework_Assert::assertTrue(
+            empty($errors),
+            'Were not found the following products:' . implode("\n", $errors)
+        );
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'All products have been successfully found.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml
index 378b643c476d848be5ed3ec0ceb960b48ef86e4e..7f383cc9f8b9b3af2a8cec41e68b9dad537ebeb9 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogSearch/Test/etc/global/constraint.xml
@@ -38,4 +38,11 @@
             <productSearch class="Magento\Catalog\Test\Fixture\CatalogProductSimple" />
         </require>
     </assertAdvancedSearchProductsResult>
+    <assertCatalogSearchResult module="Magento_CatalogSearch">
+        <severeness>high</severeness>
+        <require>
+            <cmsIndex class="Magento\Cms\Test\Page\CmsIndex" />
+            <catalogSearch class="Magento\CatalogSearch\Test\Fixture\CatalogSearchQuery" />
+        </require>
+    </assertCatalogSearchResult>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
index 6589d7c34438c10103cb1057b3b28574178785ad..077fd260ce1dee83644238848c0c3fdfcec3cf6a 100644
--- a/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Cms/Test/Handler/CmsPage/Curl.php
@@ -62,6 +62,13 @@ class Curl extends Conditions implements CmsPageInterface
         ]
     ];
 
+    /**
+     * Url for save cms page
+     *
+     * @var string
+     */
+    protected $url = 'admin/cms_page/save/back/edit/active_tab/main_section/';
+
     /**
      * Post request for creating a cms page
      *
@@ -71,7 +78,7 @@ class Curl extends Conditions implements CmsPageInterface
      */
     public function persist(FixtureInterface $fixture = null)
     {
-        $url = $_ENV['app_backend_url'] . 'admin/cms_page/save/';
+        $url = $_ENV['app_backend_url'] . $this->url;
         $data = $this->replaceMappingData($fixture->getData());
         $data['stores'] = [$data['store_id']];
         unset($data['store_id']);
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
index d01ea227cc65cbeb788233cafc344e2b194abfa4..2dba0bd3cbe63eda09e5b3e5d73170906931de21 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Attribute.php
@@ -91,26 +91,26 @@ class Attribute extends Block
     public function fillAttributeOptions(array $fields)
     {
         $row = 0;
-        foreach ($fields as $field) {
-            if (isset($field['option_label']['value'])) {
-                $optionRow = $this->getOptionRow($field['option_label']['value']);
+        foreach ($fields['options'] as $option) {
+            if (!empty($option['name'])) {
+                $optionRow = $this->getOptionRow($option['name']);
                 if (!$optionRow->isVisible()) {
                     $this->_rootElement->find($this->addOption)->click();
                     $optionRow = $this->getOptionNewRow($row);
-                    if (isset($field['option_label']['value'])) {
-                        $optionRow->find($this->labelValue)->setValue($field['option_label']['value']);
+                    if (isset($option['name'])) {
+                        $optionRow->find($this->labelValue)->setValue($option['name']);
                     }
                 }
-                if (isset($field['pricing_value']['value'])) {
+                if (isset($option['pricing_value'])) {
                     $optionRow->find($this->pricingValue, Locator::SELECTOR_CSS)
-                        ->setValue($field['pricing_value']['value']);
+                        ->setValue($option['pricing_value']);
                 }
-                if (isset($field['is_percent']['value']) && $field['is_percent']['value'] == 'Yes') {
+                if (isset($option['is_percent']) && $option['is_percent'] == 'Yes') {
                     $optionRow->find($this->priceTypeButton, Locator::SELECTOR_CSS)->click();
                     $optionRow->find($this->priceTypeValue . '//a[text()="%"]', Locator::SELECTOR_XPATH)->click();
                 }
                 $optionRow->find($this->include, Locator::SELECTOR_CSS, 'checkbox')
-                    ->setValue($field['include']['value']);
+                    ->setValue($option['include']);
             }
             ++$row;
         }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
index 47300f19804a38fa091e9c4fdbb5902f71a979d7..e33f17145d58b7082ba9d56371a70326879cfd3b 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
@@ -21,6 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\ConfigurableProduct\Test\Block\Adminhtml\Product\Edit\Tab\Super;
 
 use Mtf\Client\Element;
@@ -127,13 +128,13 @@ class Config extends Tab
             return $this;
         }
         $attributes = $fields['configurable_attributes_data']['value'];
-        foreach ($attributes as $attribute) {
-            $this->selectAttribute($attribute['label']['value']);
+        foreach ($attributes['attributes_data'] as $attribute) {
+            $this->selectAttribute($attribute['title']);
         }
         $this->fillAttributeOptions($attributes);
         $this->generateVariations();
-        if (isset($fields['variations-matrix']['value'])) {
-            $this->fillVariationsMatrix($fields['variations-matrix']['value']);
+        if (!empty($attributes['matrix'])) {
+            $this->fillVariationsMatrix($attributes['matrix']);
         }
 
         return $this;
@@ -145,7 +146,7 @@ class Config extends Tab
      * @param array $fields
      * @return void
      */
-    public function fillVariationsMatrix($fields)
+    public function fillVariationsMatrix(array $fields)
     {
         $this->getMatrixBlock()->fillVariation($fields);
     }
@@ -158,8 +159,8 @@ class Config extends Tab
      */
     public function fillAttributeOptions(array $attributes)
     {
-        foreach ($attributes as $attribute) {
-            $this->getAttributeBlock($attribute['label']['value'])->fillAttributeOptions($attribute);
+        foreach ($attributes['attributes_data'] as $attribute) {
+            $this->getAttributeBlock($attribute['title'])->fillAttributeOptions($attribute);
         }
     }
 
@@ -188,9 +189,12 @@ class Config extends Tab
                 "//div[@class='mage-suggest-dropdown']//a[text()='$attributeName']",
                 Locator::SELECTOR_XPATH
             );
-            if ($attribute->isVisible()) {
-                $attribute->click();
-            }
+            $attribute->waitUntil(
+                function () use ($attribute) {
+                    return $attribute->isVisible() ? true : null;
+                }
+            );
+            $attribute->click();
         }
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
index c6b42746512b9ed855c879f1961f2b711333d21f..2cc1ac02d41fe3c805a36f6d8410d0b0ae396b41 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.php
@@ -31,7 +31,6 @@ use Mtf\Factory\Factory;
 use Mtf\Util\XmlConverter;
 use Mtf\Block\BlockFactory;
 use Mtf\Client\Element\Locator;
-use Mtf\Fixture\FixtureInterface;
 use Magento\Catalog\Test\Fixture\CatalogCategory;
 use Magento\Catalog\Test\Block\Adminhtml\Product\ProductForm as ParentForm;
 
@@ -74,14 +73,14 @@ class ProductForm extends ParentForm
      *
      * @var string
      */
-    protected $variationsTab = '[data-ui-id="product-tabs-tab-content-super-config"] .title';
+    protected $variationsTab = '#product_info_tabs_super_config_content .title';
 
     /**
      * Variations wrapper selector
      *
      * @var string
      */
-    protected $variationsWrapper = '[data-ui-id="product-tabs-tab-content-super-config"]';
+    protected $variationsWrapper = '#product_info_tabs_super_config_content';
 
     /**
      * @param Element $element
@@ -137,43 +136,6 @@ class ProductForm extends ParentForm
         $this->category = $category;
     }
 
-    /**
-     * Fill the product form
-     *
-     * @param FixtureInterface $fixture
-     * @param Element|null $element
-     * @return $this
-     */
-    public function fill(FixtureInterface $fixture, Element $element = null)
-    {
-        $this->fillCategory($fixture);
-        parent::fill($fixture);
-        if ($fixture->getAttributeOptions()) {
-            $this->_rootElement->find($this->productDetailsTab)->click();
-            $this->clickCreateNewVariationSet();
-            $attributeBlockForm = $this->getConfigurableAttributeEditBlock();
-            $attributeBlockForm->fillAttributeOption($fixture->getAttributeOptions());
-        }
-        if ($fixture->getConfigurableOptions()) {
-            $this->browser->switchToFrame();
-            $this->variationsFill($fixture->getConfigurableOptions());
-        }
-    }
-
-    /**
-     * Save product
-     *
-     * @param FixtureInterface $fixture
-     * @return \Magento\Backend\Test\Block\Widget\Form|void
-     */
-    public function save(FixtureInterface $fixture = null)
-    {
-        parent::save($fixture);
-        if ($this->getAffectedAttributeSetBlock()->isVisible()) {
-            $this->getAffectedAttributeSetBlock()->chooseAttributeSet($fixture);
-        }
-    }
-
     /**
      * Get variations block
      *
@@ -190,6 +152,7 @@ class ProductForm extends ParentForm
      * Fill product variations
      *
      * @param array $variations
+     * @return void
      */
     public function variationsFill(array $variations)
     {
@@ -200,6 +163,8 @@ class ProductForm extends ParentForm
 
     /**
      * Open variations tab
+     *
+     * @return void
      */
     public function openVariationsTab()
     {
@@ -208,6 +173,8 @@ class ProductForm extends ParentForm
 
     /**
      * Click on 'Create New Variation Set' button
+     *
+     * @return void
      */
     public function clickCreateNewVariationSet()
     {
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
index 1362f3e17afe14614c551e695c008dae49735861..eb831ebbe03b82b7cf434bc33769c103411ba5b6 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Block/Adminhtml/Product/ProductForm.xml
@@ -36,12 +36,14 @@
             <is_virtual>
                 <input>checkbox</input>
             </is_virtual>
-            <qty>
-                <selector>[name='product[quantity_and_stock_status][qty]']</selector>
-            </qty>
-            <quantity_and_stock_status>
-                <selector>[name='product[quantity_and_stock_status][is_in_stock]']</selector>
-                <input>select</input>
+            <quantity_and_stock_status composite="1">
+                <qty>
+                    <selector>#qty</selector>
+                </qty>
+                <is_in_stock>
+                    <selector>#quantity_and_stock_status</selector>
+                    <input>select</input>
+                </is_in_stock>
             </quantity_and_stock_status>
         </fields>
     </product-details>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
index 70953f1bde5b6861ae50787821920424280d36dc..b4f2372942cd3a830170a8db95fcf40b991a494c 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCart.php
@@ -57,12 +57,12 @@ class AssertConfigurableInCart extends AbstractConstraint
         //Add product to cart
         $catalogProductView->init($configurable);
         $catalogProductView->open();
-        $productOptions = $configurable->getConfigurableOptions();
-        if ($productOptions) {
+        $configurableData = $configurable->getConfigurableAttributesData();
+        if (!empty($configurableData)) {
             $configurableOption = $catalogProductView->getCustomOptionsBlock();
-            $options = $configurableOption->getOptions();
-            $key = $productOptions['value']['label']['value'];
-            $configurableOption->selectProductCustomOption(reset($options[$key]['value']));
+            foreach ($configurableData['attributes_data'] as $attribute) {
+                $configurableOption->selectProductCustomOption(reset($attribute['options'])['name']);
+            }
         }
         $catalogProductView->getViewBlock()->clickAddToCart();
 
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
index 19b546ec68af83481e6e517ffd0acd2be5b3e22c..40389e96bda98cd534118796920c14598f8117aa 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertConfigurableInCategory.php
@@ -24,8 +24,8 @@
 
 namespace Magento\ConfigurableProduct\Test\Constraint;
 
-use Mtf\Constraint\AbstractConstraint;
 use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Fixture\CatalogCategory;
 use Magento\Catalog\Test\Page\Category\CatalogCategoryView;
 use Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
index 53e690f919eeb46e4d8272dff6ab270448452bce..ec83346fc0876233cbcc69aadcb1c292faebc9af 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Constraint/AssertProductAttributeIsConfigurable.php
@@ -46,9 +46,9 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
     /**
      * Attribute frontend label
      *
-     * @var string
+     * @var CatalogProductAttribute
      */
-    protected $attributeFrontendLabel;
+    protected $attribute;
 
     /**
      * Assert check whether the attribute is used to create a configurable products
@@ -67,9 +67,7 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
         CatalogProductNew $newProductPage,
         CatalogProductAttribute $productAttribute = null
     ) {
-        $this->attributeFrontendLabel = ($productAttribute)
-            ? $productAttribute->getFrontendLabel()
-            : $attribute->getFrontendLabel();
+        $this->attribute = !is_null($productAttribute) ? $productAttribute : $attribute;
         $productGrid->open();
         $productGrid->getProductBlock()->addProduct('configurable');
 
@@ -79,10 +77,9 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
                 'dataSet' => 'default',
                 'data' => [
                     'configurable_attributes_data' => [
-                        'value' => [
-                            'label' => [
-                                'value' => $this->attributeFrontendLabel
-                            ]
+                        'preset' => 'one_variations',
+                        'attributes' => [
+                            $this->attribute
                         ]
                     ]
                 ],
@@ -90,21 +87,21 @@ class AssertProductAttributeIsConfigurable extends AbstractConstraint
         );
 
         $productBlockForm = $newProductPage->getForm();
-        $productBlockForm->fill($productConfigurable);
+        $productBlockForm->fillProduct($productConfigurable);
 
         \PHPUnit_Framework_Assert::assertTrue(
-            $newProductPage->getForm()->findAttribute($this->attributeFrontendLabel),
-            "Product Attribute is absent on Product page."
+            $newProductPage->getForm()->findAttribute($this->attribute->getFrontendLabel()),
+            "Product attribute is absent on the product page."
         );
     }
 
     /**
-     * Attribute '$this->attributeFrontendLabel' present on the product page in variations section
+     * Attribute label present on the product page in variations section
      *
      * @return string
      */
     public function toString()
     {
-        return "$this->attributeFrontendLabel attribute present on the product page in variations section";
+        return 'Attribute label, present on the product page in variations section.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
index 9911c1543b1388be915cab36d5b7b24675d1bfb5..f985d2fe282702e26467e3a880c56b70e604a434 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.php
@@ -44,11 +44,12 @@ class CatalogProductConfigurable extends InjectableFixture
      */
     protected $repositoryClass = 'Magento\ConfigurableProduct\Test\Repository\CatalogProductConfigurable';
 
+    // @codingStandardsIgnoreStart
     /**
      * @var string
      */
-    protected $handlerInterface =
-        'Magento\ConfigurableProduct\Test\Handler\CatalogProductConfigurable\CatalogProductConfigurableInterface';
+    protected $handlerInterface = 'Magento\ConfigurableProduct\Test\Handler\CatalogProductConfigurable\CatalogProductConfigurableInterface';
+    // @codingStandardsIgnoreEnd
 
     /**
      * Constructor
@@ -83,6 +84,7 @@ class CatalogProductConfigurable extends InjectableFixture
             $dataSet,
             $persist
         );
+
         if (!isset($this->data['url_key']) && isset($this->data['name'])) {
             $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-');
         }
@@ -372,7 +374,7 @@ class CatalogProductConfigurable extends InjectableFixture
         'default_value' => '',
         'input' => 'price',
         'group' => 'product-details',
-        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\Price'
+        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\Price'
     ];
 
     protected $quantity_and_stock_status = [
@@ -462,8 +464,9 @@ class CatalogProductConfigurable extends InjectableFixture
         'attribute_code' => 'status',
         'backend_type' => 'int',
         'is_required' => '0',
-        'default_value' => '',
-        'input' => 'select',
+        'default_value' => 'Product online',
+        'input' => 'checkbox',
+        'group' => 'product-details',
     ];
 
     protected $tax_class_id = [
@@ -558,6 +561,8 @@ class CatalogProductConfigurable extends InjectableFixture
     protected $attribute_set_id = [
         'attribute_code' => 'attribute_set_id',
         'backend_type' => 'virtual',
+        'group' => 'product-details',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId',
     ];
 
     protected $attribute_set_name = [
@@ -566,12 +571,6 @@ class CatalogProductConfigurable extends InjectableFixture
         'group' => 'variations'
     ];
 
-    protected $qty = [
-        'attribute_code' => 'qty',
-        'input' => 'input',
-        'group' => 'product-details',
-    ];
-
     protected $custom_options = [
         'attribute_code' => 'custom_options',
         'backend_type' => 'virtual',
@@ -580,38 +579,19 @@ class CatalogProductConfigurable extends InjectableFixture
         'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
     ];
 
-    protected $configurable_options = [
-        'attribute_code' => 'configurable_options',
-        'backend_type' => 'virtual',
-        'is_required' => '0',
-        'input' => 'variations',
-        'group' => 'product-details',
-        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions',
-    ];
-
-    protected $attribute_options = [
-        'attribute_code' => 'attribute_options',
-        'backend_type' => 'virtual',
-        'is_required' => '0',
-        'input' => 'variations',
-        'group' => 'product-details',
-        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\AttributeOptions',
-    ];
-
     protected $configurable_attributes_data = [
-        'attribute_code' => 'configurable_options_data',
+        'attribute_code' => 'configurable_attributes_data',
         'backend_type' => 'virtual',
         'is_required' => '0',
         'input' => 'variations',
         'group' => 'variations',
+        'source' => 'Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableAttributesData'
     ];
 
-    protected $variations_matrix = [
-        'attribute_code' => 'variations_matrix',
+    protected $website_ids = [
+        'attribute_code' => 'website_ids',
         'backend_type' => 'virtual',
-        'is_required' => '0',
-        'input' => 'variations',
-        'group' => 'variations',
+        'default_value' => 'Main Website',
     ];
 
     public function getCategoryIds()
@@ -894,28 +874,23 @@ class CatalogProductConfigurable extends InjectableFixture
         return $this->getData('attribute_set_id');
     }
 
-    public function getQty()
-    {
-        return $this->getData('qty');
-    }
-
     public function getCustomOptions()
     {
         return $this->getData('custom_options');
     }
 
-    public function getConfigurableOptions()
+    public function getAttributeSetName()
     {
-        return $this->getData('configurable_options');
+        return $this->getData('attribute_set_name');
     }
 
-    public function getAttributeOptions()
+    public function getConfigurableAttributesData()
     {
-        return $this->getData('attribute_options');
+        return $this->getData('configurable_attributes_data');
     }
 
-    public function getAttributeSetName()
+    public function getWebsiteIds()
     {
-        return $this->getData('attribute_set_name');
+        return $this->getData('website_ids');
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml
index d985971cbcc36216c04384a42bc70485ed45765c..b37c96cd976cc7c19d1068794eac7499806f5bad 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable.xml
@@ -38,6 +38,14 @@
             <default_value></default_value>
             <input>text</input>
         </category_ids>
+        <configurable_attributes_data>
+            <attribute_code>configurable_attributes_data</attribute_code>
+            <backend_type>virtual</backend_type>
+            <is_required>0</is_required>
+            <input>variations</input>
+            <group>variations</group>
+            <source>Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable\ConfigurableAttributesData</source>
+        </configurable_attributes_data>
         <color>
             <attribute_code>color</attribute_code>
             <backend_type>int</backend_type>
@@ -122,7 +130,7 @@
             <default_value></default_value>
             <input>text</input>
             <group>advanced-pricing</group>
-            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions</fixture>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\GroupPriceOptions</source>
         </group_price>
         <has_options>
             <attribute_code>has_options</attribute_code>
@@ -265,7 +273,7 @@
             <default_value></default_value>
             <input>price</input>
             <group>product_info_tabs_product-details</group>
-            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</fixture>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\Price</source>
         </price>
         <quantity_and_stock_status>
             <attribute_code>quantity_and_stock_status</attribute_code>
@@ -344,8 +352,9 @@
             <attribute_code>status</attribute_code>
             <backend_type>int</backend_type>
             <is_required>0</is_required>
-            <default_value>1</default_value>
-            <input>select</input>
+            <default_value>Product online</default_value>
+            <input>checkbox</input>
+            <group>product-details</group>
         </status>
         <tax_class_id>
             <attribute_code>tax_class_id</attribute_code>
@@ -423,39 +432,27 @@
         </type_id>
         <attribute_set_id>
             <attribute_code>attribute_set_id</attribute_code>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId</source>
             <backend_type>virtual</backend_type>
+            <group>product-details</group>
         </attribute_set_id>
         <attribute_set_name>
             <attribute_code>attribute_set_name</attribute_code>
             <backend_type>virtual</backend_type>
             <group>product-details</group>
         </attribute_set_name>
-        <qty>
-            <attribute_code>qty</attribute_code>
-            <input>input</input>
-            <group>product_info_tabs_product-details</group>
-        </qty>
         <custom_options>
             <attribute_code>custom_options</attribute_code>
             <backend_type>virtual</backend_type>
             <group>product_info_tabs_customer_options</group>
             <is_required>0</is_required>
-            <fixture>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</fixture>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions</source>
         </custom_options>
-        <configurable_options>
-            <attribute_code>configurable_options</attribute_code>
-            <backend_type>virtual</backend_type>
-            <group>product-details</group>
-            <is_required>0</is_required>
-            <fixture>Magento\ConfigurableProducts\Test\Fixture\CatalogProductConfigurable\ConfigurableOptions</fixture>
-        </configurable_options>
-        <attribute_options>
-            <attribute_code>configurable_options</attribute_code>
+        <website_ids>
+            <attribute_code>website_ids</attribute_code>
             <backend_type>virtual</backend_type>
-            <group>product-details</group>
-            <is_required>0</is_required>
-            <fixture>Magento\ConfigurableProducts\Test\Fixture\CatalogProductConfigurable\AttributeOptions</fixture>
-        </attribute_options>
+            <default_value>Main Website</default_value>
+        </website_ids>
     </fields>
     <data_set>
         <sku></sku>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e9beb70f817bd6b82c13757d07c9ab61e5b49ba
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableAttributesData.php
@@ -0,0 +1,572 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class ConfigurableAttributesData
+ * Source configurable attributes data of the configurable products
+ */
+class ConfigurableAttributesData implements FixtureInterface
+{
+    /**
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data = [
+        'products' => [],
+        'attributes' => []
+    ];
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Current preset
+     *
+     * @var string
+     */
+    protected $currentPreset;
+
+    /**
+     * Fixture factory
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Source constructor
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @param array $data
+     * @param array $params [optional]
+     *
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = [])
+    {
+        $this->fixtureFactory = $fixtureFactory;
+        $this->params = $params;
+        $data['products'] = empty($data['products']) ? [] : $data['products'];
+        $data['attributes'] = empty($data['attributes']) ? [] : $data['attributes'];
+
+        if (isset($data['preset']) && $data['preset'] !== '-') {
+            $this->currentPreset = $data['preset'];
+            $this->data = $this->getPreset($this->currentPreset);
+            unset($data['preset']);
+        }
+
+        foreach ($data['products'] as $key => $product) {
+            $this->data['products'][$key] = $product;
+        }
+        foreach ($data['attributes'] as $key => $attribute) {
+            $this->data['attributes'][$key] = $attribute;
+        }
+
+        $this->prepareProducts();
+        $this->prepareAttributes();
+    }
+
+    /**
+     * Persist configurable attribute data
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Preparation of products fixture
+     *
+     * @return void
+     */
+    protected function prepareProducts()
+    {
+        if (!empty($this->data['products'])) {
+            foreach ($this->data['products'] as $key => $product) {
+                if (is_string($product)) {
+                    list($fixture, $dataSet) = explode('::', $product);
+                    /** @var $product InjectableFixture */
+                    $product = $this->fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                    if (!$product->hasData('id')) {
+                        $product->persist();
+                    }
+                }
+                $this->data['products'][$key] = $product;
+            }
+        }
+    }
+
+    /**
+     * Preparation of attributes fixture
+     *
+     * @return void
+     */
+    protected function prepareAttributes()
+    {
+        if (!empty($this->data['attributes'])) {
+            foreach ($this->data['attributes'] as $key => $attribute) {
+                if (is_string($attribute)) {
+                    list($fixture, $dataSet) = explode('::', $attribute);
+                    /** @var $attribute InjectableFixture */
+                    $attribute = $this->fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                    if (!$attribute->hasData('id')) {
+                        $attribute->persist();
+                    }
+                }
+                $this->data['attributes'][$key] = $attribute;
+            }
+            // Set options used.
+            $this->setOptions();
+            // Initialization data matrix
+            $this->matrixInit();
+            // Assigning products
+            $this->assigningProducts();
+        }
+    }
+
+    /**
+     * Set options used
+     *
+     * @return void
+     *
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function setOptions()
+    {
+        $fixtures = $this->data['attributes'];
+        foreach (array_keys($this->data['attributes_data']) as $key) {
+            $fixtureData = $fixtures[$key]->getData();
+            $this->data['attributes_data'][$key]['id'] = isset($fixtureData['attribute_id'])
+                ? $fixtureData['attribute_id']
+                : $key;
+            $this->data['attributes_data'][$key]['title'] = $fixtureData['frontend_label'];
+            $this->data['attributes_data'][$key]['code'] = $fixtureData['frontend_label'];
+            foreach ($this->data['attributes_data'][$key]['options'] as $optionKey => &$value) {
+                if (!isset($fixtureData['options'][$optionKey])) {
+                    unset($this->data['attributes_data'][$key]['options'][$optionKey]);
+                    continue;
+                }
+                $value['id'] = isset($fixtureData['options'][$optionKey]['id'])
+                    ? $fixtureData['options'][$optionKey]['id']
+                    : $optionKey;
+                $value['name'] = empty($fixtureData['options'][$optionKey]['view'])
+                    ? $fixtureData['options'][$optionKey]['admin']
+                    : $fixtureData['options'][$optionKey]['view'];
+            }
+            unset($value);
+        }
+    }
+
+    /**
+     * Prepare data for matrix
+     *
+     * @return array
+     */
+    protected function prepareDataMatrix()
+    {
+        $attributes = [];
+        foreach ($this->data['attributes_data'] as $attributeKey => $attribute) {
+            $options = [];
+            foreach ($attribute['options'] as $optionKey => $option) {
+                if ($option['include'] === 'Yes') {
+                    $option['key'] = $optionKey;
+                    $options[] = $option;
+                }
+            }
+            $attributes[] = [
+                'key' => $attributeKey,
+                'id' => $attribute['id'],
+                'code' => $attribute['code'],
+                'options' => $options
+            ];
+        }
+
+        return $attributes;
+    }
+
+    /**
+     * Generation variants
+     *
+     * @return array
+     */
+    protected function generationVariants()
+    {
+        $attributes = array_reverse($this->prepareDataMatrix());
+        $variations = [];
+        $attributesCount = count($attributes);
+        $currentVariation = array_fill(0, $attributesCount, 0);
+        $lastAttribute = $attributesCount - 1;
+        do {
+            for ($attributeIndex = 0; $attributeIndex < $attributesCount - 1; ++$attributeIndex) {
+                if ($currentVariation[$attributeIndex] >= count($attributes[$attributeIndex]['options'])) {
+                    $currentVariation[$attributeIndex] = 0;
+                    ++$currentVariation[$attributeIndex + 1];
+                }
+            }
+            if ($currentVariation[$lastAttribute] >= count($attributes[$lastAttribute]['options'])) {
+                break;
+            }
+
+            $filledVariation = [];
+            for ($attributeIndex = $attributesCount; $attributeIndex--;) {
+                $currentAttribute = $attributes[$attributeIndex];
+                $currentVariationValue = $currentVariation[$attributeIndex];
+                $filledVariation[$currentAttribute['key']] = $currentAttribute['options'][$currentVariationValue];
+                $filledVariation[$currentAttribute['key']]['code'] = $currentAttribute['code'];
+            }
+
+            $variationsKeys = [];
+            $placeholder = [];
+            $optionsNames = [];
+            foreach ($filledVariation as $key => $option) {
+                $variationKey = sprintf('%%attribute_%d-option_%d%%', $key, $option['key']);
+                $variationsKeys[] = $variationKey;
+                $keyName = sprintf('%%attribute_%d-option_%d_name%%', $key, $option['key']);
+                $keyId = sprintf('%%attribute_%d-option_%d_id%%', $key, $option['key']);
+                $attributeCode = sprintf('%%attribute_%d_code%%', $key);
+                $optionsNames[] = $option['name'];
+                $placeholder += [
+                    $keyName => $option['name'],
+                    $keyId => $option['id'],
+                    $variationKey => $option['id'],
+                    $attributeCode => $option['code']
+                ];
+            }
+
+            $variationsKey = implode('-', $variationsKeys);
+            $variations[$variationsKey]['placeholder'] = $placeholder;
+            $variations[$variationsKey]['options_names'] = $optionsNames;
+            $currentVariation[0]++;
+        } while (true);
+
+        return $variations;
+    }
+
+    /**
+     * Initialization data matrix
+     *
+     * @return void
+     */
+    protected function matrixInit()
+    {
+        // Generation variants
+        $variations = $this->generationVariants();
+
+        foreach (array_keys($this->data['matrix']) as $key) {
+            if (isset($variations[$key])) {
+                foreach ($this->data['matrix'][$key] as $innerKey => &$value) {
+                    if ($innerKey === 'configurable_attribute') {
+                        $value = strtr(json_encode($value), $variations[$key]['placeholder']);
+                    } elseif (is_string($value)) {
+                        $value = strtr($value, $variations[$key]['placeholder']);
+                    }
+                }
+                unset($value);
+                $newKey = strtr($key, $variations[$key]['placeholder']);
+                $this->data['matrix'][$newKey] = $this->data['matrix'][$key];
+                $this->data['matrix'][$newKey]['options_names'] = $variations[$key]['options_names'];
+                unset($this->data['matrix'][$key]);
+            }
+        }
+    }
+
+    /**
+     * Assigning products
+     *
+     * @return void
+     */
+    protected function assigningProducts()
+    {
+        foreach ($this->data['products'] as $key => $product) {
+            foreach ($this->data['matrix'] as &$value) {
+                if (isset($value['associated_product_ids'][$key])) {
+                    unset($value['associated_product_ids'][$key]);
+                    /** @var $attribute InjectableFixture */
+                    $value['associated_product_ids'][] = $product->getId();
+                    $value['name'] = $product->getName();
+                    $value['sku'] = $product->getSku();
+                }
+            }
+            unset($value);
+        }
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string|null $key
+     * @return mixed
+     */
+    public function getData($key = null)
+    {
+        return isset($this->data[$key]) ? $this->data[$key] : $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Preset array
+     *
+     * @param string $name
+     * @return mixed|null
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function getPreset($name)
+    {
+        $presets = [
+            'default' => [
+                'attributes_data' => [
+                    [
+                        'id' => '%id%',
+                        'title' => '%title%',
+                        'label' => 'Test variation1 label',
+                        'options' => [
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 12.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 20.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 18.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                        ]
+                    ],
+                    [
+                        'id' => '%id%',
+                        'title' => '%title%',
+                        'label' => 'Test variation2 label',
+                        'options' => [
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 42.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 40.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 48.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ],
+                        ]
+                    ]
+                ],
+                'products' => [
+
+                ],
+                'attributes' => [
+                    'catalogProductAttribute::attribute_type_dropdown',
+                    'catalogProductAttribute::attribute_type_dropdown'
+                ],
+                'matrix' => [
+                    '%attribute_0-option_0%-%attribute_1-option_0%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_0%',
+                            '%attribute_1_code%' => '%attribute_1-option_0%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_0_name% %attribute_1-option_0_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%_%attribute_1-option_0_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_0%-%attribute_1-option_1%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_0%',
+                            '%attribute_1_code%' => '%attribute_1-option_1%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_0_name% %attribute_1-option_1_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%_%attribute_1-option_1_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_0%-%attribute_1-option_2%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_0%',
+                            '%attribute_1_code%' => '%attribute_1-option_2%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_0_name% %attribute_1-option_2_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%_%attribute_1-option_2_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_1%-%attribute_1-option_0%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_1%',
+                            '%attribute_1_code%' => '%attribute_1-option_0%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_0_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_0_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_1%-%attribute_1-option_1%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_1%',
+                            '%attribute_1_code%' => '%attribute_1-option_1%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_1_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_1_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_1%-%attribute_1-option_2%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_1%',
+                            '%attribute_1_code%' => '%attribute_1-option_2%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_1_name% %attribute_1-option_2_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_1_id%_%attribute_1-option_2_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_2%-%attribute_1-option_0%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_2%',
+                            '%attribute_1_code%' => '%attribute_1-option_0%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_0_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_0_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_2%-%attribute_1-option_1%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_2%',
+                            '%attribute_1_code%' => '%attribute_1-option_1%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_1_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_1_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ],
+                    '%attribute_0-option_2%-%attribute_1-option_2%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_2%',
+                            '%attribute_1_code%' => '%attribute_1-option_2%'
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_2_name% %attribute_1-option_2_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_2_id%_%attribute_1-option_2_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ]
+                ]
+            ],
+            'one_variations' => [
+                'attributes_data' => [
+                    [
+                        'id' => '%id%',
+                        'title' => '%title%',
+                        'label' => 'Test variation1 label',
+                        'options' => [
+                            [
+                                'id' => '%id%',
+                                'name' => '%name%',
+                                'pricing_value' => 12.00,
+                                'include' => 'Yes',
+                                'is_percent' => 'No'
+                            ]
+                        ]
+                    ]
+                ],
+                'products' => [
+
+                ],
+                'attributes' => [
+                    'catalogProductAttribute::attribute_type_dropdown'
+                ],
+                'matrix' => [
+                    '%attribute_0-option_0%' => [
+                        'configurable_attribute' => [
+                            '%attribute_0_code%' => '%attribute_0-option_0%',
+                        ],
+                        'associated_product_ids' => [],
+                        'name' => 'In configurable %isolation% %attribute_0-option_0_name%',
+                        'sku' => 'sku_configurable_%isolation%_%attribute_0-option_0_id%',
+                        'qty' => 10,
+                        'weight' => 1
+                    ]
+                ]
+            ]
+        ];
+
+        if (!isset($presets[$name])) {
+            return null;
+        }
+
+        return $presets[$name];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableOptions.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableOptions.php
deleted file mode 100644
index 3522a77313ea2f6a4dc9b41f4615d9691ddf991c..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/ConfigurableOptions.php
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
-
-use Mtf\Fixture\FixtureFactory;
-use Mtf\Fixture\FixtureInterface;
-
-/**
- * Class ConfigurableOptions
- *
- * Data keys:
- *  - preset (Configurable options preset name)
- *  - products (comma separated sku identifiers)
- *
- */
-class ConfigurableOptions implements FixtureInterface
-{
-    /**
-     * @var \Mtf\Fixture\FixtureFactory
-     */
-    protected $fixtureFactory;
-
-    /**
-     * @param array $params
-     * @param array $data
-     */
-    public function __construct(array $params, array $data = [])
-    {
-        $this->params = $params;
-        if (isset($data['preset'])) {
-            $this->data = $this->getPreset($data['preset']);
-        }
-    }
-
-    /**
-     * Persist configurable product options
-     *
-     * @return void
-     */
-    public function persist()
-    {
-        //
-    }
-
-    /**
-     * Return prepared data set
-     *
-     * @param $key [optional]
-     * @return mixed
-     *
-     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
-     */
-    public function getData($key = null)
-    {
-        return $this->data;
-    }
-
-    /**
-     * Return data set configuration settings
-     *
-     * @return string
-     */
-    public function getDataConfig()
-    {
-        return $this->params;
-    }
-
-    /**
-     * @param string $name
-     * @return array|null
-     */
-    protected function getPreset($name)
-    {
-        $presets = [
-            'configurable_attributes_data' => [
-                'value' => [
-                    'label' => [
-                        'value' => 'test%isolation%'
-                    ],
-                    '0' => [
-                        'option_label' => [
-                            'value' => 'option 0'
-                        ],
-                        'pricing_value' => [
-                            'value' => '30'
-                        ],
-                        'is_percent' => [
-                            'value' => 'No'
-                        ],
-                        'include' => [
-                            'value' => 'Yes'
-                        ],
-                    ],
-                    '1' => [
-                        'option_label' => [
-                            'value' => 'option 1'
-                        ],
-                        'pricing_value' => [
-                            'value' => '40'
-                        ],
-                        'is_percent' => [
-                            'value' => 'No'
-                        ],
-                        'include' => [
-                            'value' => 'Yes'
-                        ],
-                    ]
-                ]
-            ]
-        ];
-        if (!isset($presets[$name])) {
-            return null;
-        }
-        return $presets[$name];
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/Price.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/Price.php
index b8c21146c70250a5fb8b3dc0cc6cfa32882381e2..918f84757d5ca798a0fbd8bc9fe6b203c1ddeefc 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/Price.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/Price.php
@@ -24,7 +24,6 @@
 
 namespace Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
 
-use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
 
 /**
@@ -33,23 +32,35 @@ use Mtf\Fixture\FixtureInterface;
  * Data keys:
  *  - preset (Price verification preset name)
  *  - value (Price value)
- *
  */
 class Price implements FixtureInterface
 {
     /**
-     * @var \Mtf\Fixture\FixtureFactory
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
      */
-    protected $fixtureFactory;
+    protected $params;
 
     /**
+     * Current preset
+     *
      * @var string
      */
     protected $currentPreset;
 
     /**
+     * Constructor
+     *
      * @param array $params
-     * @param array $data
+     * @param array $data [optional]
      */
     public function __construct(array $params, array $data = [])
     {
@@ -75,7 +86,7 @@ class Price implements FixtureInterface
     /**
      * Return prepared data set
      *
-     * @param $key [optional]
+     * @param string|null $key [optional]
      * @return mixed
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
@@ -102,19 +113,21 @@ class Price implements FixtureInterface
     {
         $presets = [
             'MAGETWO-23062' => [
-                'category_price' => '$100.00',
-                'product_price' => '$100.00',
-                'cart_price' => '$130.00'
+                'category_price' => '100.00',
+                'product_price' => '100.00',
+                'cart_price' => '154.00'
             ],
             'MAGETWO-23063' => [
-                'category_price' => '$100.00',
-                'product_price' => '$100.00',
-                'cart_price' => '$140.00'
+                'category_price' => '100.00',
+                'product_price' => '100.00',
+                'cart_price' => '140.00'
             ],
         ];
+
         if (!isset($presets[$this->currentPreset])) {
             return null;
         }
+
         return $presets[$this->currentPreset];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/CatalogProductConfigurableInterface.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/CatalogProductConfigurableInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..dba4fea8b1d3aa887de470ab1ae1da9b4098211e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/CatalogProductConfigurableInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\ConfigurableProduct\Test\Handler\CatalogProductConfigurable;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CatalogProductConfigurableInterface
+ */
+interface CatalogProductConfigurableInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/Curl.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..a33deec3fec0b1efaf8e7124195242447173024a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Handler/CatalogProductConfigurable/Curl.php
@@ -0,0 +1,169 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\ConfigurableProduct\Test\Handler\CatalogProductConfigurable;
+
+use Mtf\System\Config;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
+
+/**
+ * Class Curl
+ * Create new configurable product via curl
+ */
+class Curl extends ProductCurl implements CatalogProductConfigurableInterface
+{
+    /**
+     * Constructor
+     *
+     * @param Config $configuration
+     */
+    public function __construct(Config $configuration)
+    {
+        parent::__construct($configuration);
+
+        $this->mappingData += [
+            'is_percent' => [
+                'Yes' => 1,
+                'No' => 0
+            ],
+            'include' => [
+                'Yes' => 1,
+                'No' => 0
+            ]
+        ];
+    }
+
+    /**
+     * Prepare POST data for creating product request
+     *
+     * @param FixtureInterface $fixture
+     * @param string|null $prefix [optional]
+     * @return array
+     */
+    protected function prepareData(FixtureInterface $fixture, $prefix = null)
+    {
+        $data = parent::prepareData($fixture, null);
+        $attributeSetId = $data['attribute_set_id'];
+        $matrix = $data['configurable_attributes_data']['matrix'];
+        $attributesData = $data['configurable_attributes_data']['attributes_data'];
+        unset($data['configurable_attributes_data'], $data['attribute_set_id']);
+
+        // Preparing attribute data
+        $attributesIds = [];
+        $data['configurable_attributes_data'] = $this->preparingAttributeData($attributesData, $attributesIds);
+        $matrix = $this->preparingMatrixData(
+            $matrix,
+            [
+                '%product_name%' => $data['name'],
+                '%product_sku%' => $data['sku'],
+            ]
+        );
+
+        // Add prefix data
+        $data = $prefix ? [$prefix => $data] : $data;
+        $data['attributes'] = $attributesIds;
+
+        $data = array_merge($data, $this->prepareVariationsMatrix($matrix));
+        $data['new-variations-attribute-set-id'] = $attributeSetId;
+
+        return $this->replaceMappingData($data);
+    }
+
+    /**
+     * Preparing attribute data
+     *
+     * @param array $attributesData
+     * @param array $attributesIds [link]
+     * @return array
+     */
+    protected function preparingAttributeData(array $attributesData, array &$attributesIds)
+    {
+        $data = [];
+        foreach ($attributesData as $attribute) {
+            $attributesIds[] = $attribute['id'];
+            $data[$attribute['id']] = [];
+            $dataOption = & $data[$attribute['id']];
+            $dataOption['code'] = $attribute['title'];
+            $dataOption['label'] = $attribute['title'];
+            $dataOption['attribute_id'] = $attribute['id'];
+            foreach ($attribute['options'] as $option) {
+                $dataOption['values'][$option['id']]['pricing_value'] = $option['pricing_value'];
+                $dataOption['values'][$option['id']]['is_percent'] = $option['is_percent'];
+                $dataOption['values'][$option['id']]['include'] = $option['include'];
+                $dataOption['values'][$option['id']]['value_index'] = $option['id'];
+            }
+        }
+
+        return $data;
+    }
+
+    /**
+     * Preparing matrix data
+     *
+     * @param array $matrix
+     * @param array $placeholder
+     * @return array
+     */
+    protected function preparingMatrixData(array $matrix, array $placeholder)
+    {
+        foreach (array_keys($matrix) as $key) {
+            foreach ($matrix[$key] as &$value) {
+                if (is_string($value)) {
+                    $value = strtr($value, $placeholder);
+                }
+            }
+        }
+
+        return $matrix;
+    }
+
+    /**
+     * Prepare variations matrix data
+     *
+     * @param array $matrix
+     * @return array
+     */
+    protected function prepareVariationsMatrix(array $matrix)
+    {
+        $data = [
+            'variations-matrix' => [],
+            'associated_product_ids' => []
+        ];
+        foreach ($matrix as $key => $variation) {
+            $data['associated_product_ids'] = array_merge(
+                $data['associated_product_ids'],
+                $variation['associated_product_ids']
+            );
+            $data['variations-matrix'][$key]['name'] = $variation['name'];
+            $data['variations-matrix'][$key]['configurable_attribute'] = $variation['configurable_attribute'];
+            $data['variations-matrix'][$key]['sku'] = $variation['sku'];
+            $data['variations-matrix'][$key]['quantity_and_stock_status']['qty'] = $variation['qty'];
+            $data['variations-matrix'][$key]['weight'] = $variation['weight'];
+        }
+
+        return $data;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/CatalogProductConfigurable.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/CatalogProductConfigurable.php
index 7206777cb85de819d7b5fa8e9c25f6ee0301802b..b1d345f0c632c4a6e7cb0d64072996a093f6b5ab 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/CatalogProductConfigurable.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/CatalogProductConfigurable.php
@@ -33,18 +33,30 @@ use Mtf\Repository\AbstractRepository;
 class CatalogProductConfigurable extends AbstractRepository
 {
     /**
-     * @param array $defaultConfig
-     * @param array $defaultData
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function __construct(array $defaultConfig = [], array $defaultData = [])
     {
         $this->_data['default'] = [
-            'name' => 'Configurable Product %isolation%',
-            'sku' => 'sku_configurable_product_%isolation%',
-            'price' => ['value' => 100.00],
-            'weight' => 1
+            'name' => 'Test configurable product %isolation%',
+            'sku' => 'sku_test_configurable_product_%isolation%',
+            'price' => ['value' => 120.00],
+            'weight' => 30.0000,
+            'status' => 'Product online',
+            'visibility' => 'Catalog, Search',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'url_key' => 'test-configurable-product-%isolation%',
+            'configurable_attributes_data' => ['preset' => 'default'],
+            'quantity_and_stock_status' => [
+                'is_in_stock' => 'In Stock',
+            ],
+            'website_ids' => ['Main Website'],
+            'attribute_set_id' => ['dataSet' => 'default'],
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
index acaad382330953e0e4ca9d45f15114129ef4bfc2..dc214e17b828d97b06fef6ee9213a3c15bd66698 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest.php
@@ -67,6 +67,8 @@ class CreateConfigurableEntityTest extends Injectable
     protected $newProductPage;
 
     /**
+     * Prepare data
+     *
      * @param CatalogCategory $category
      * @return array
      */
@@ -80,6 +82,8 @@ class CreateConfigurableEntityTest extends Injectable
     }
 
     /**
+     * Inject data
+     *
      * @param CatalogCategory $category
      * @param CatalogProductIndex $productPageGrid
      * @param CatalogProductNew $newProductPage
@@ -108,8 +112,7 @@ class CreateConfigurableEntityTest extends Injectable
         $this->productPageGrid->getProductBlock()->addProduct('configurable');
         // Fill form
         $productBlockForm = $this->newProductPage->getConfigurableProductForm();
-        $productBlockForm->setCategory($category);
-        $productBlockForm->fill($configurable);
+        $productBlockForm->fillProduct($configurable, $category);
         $this->newProductPage->getFormAction()->saveProduct($this->newProductPage, $configurable);
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv
index f8bec073a2d9f5cfa9af6ca06272770b14b975ac..628ab880371262a2e115516f9378b4ca46eea3c4 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/TestCase/Product/CreateConfigurableEntityTest/testCreate.csv
@@ -1,2 +1,2 @@
-"configurable/data/name"; "configurable/data/sku"; "configurable/data/price/value"; "configurable/data/weight"; "configurable/data/qty"; "configurable/data/quantity_and_stock_status"; "configurable/data/visibility"; "constraint"; "configurable/data/price/preset"; "configurable/data/configurable_options/preset"; "configurable/data/attribute_options/preset"; "configurable/data/attribute_set_name"
-"Configurable %isolation%"; "conf_sku_%isolation%";"100";"1";"-";"-";"-"; "assertProductSaveMessage, assertConfigurableInGrid, assertConfigurableInCategory, assertConfigurableView, assertConfigurableInCart";"MAGETWO-23062";"configurable_attributes_data"; "MAGETWO-23263"; "AttrSet %isolation%"
+"configurable/data/name"; "configurable/data/sku"; "configurable/data/price/value"; "configurable/data/weight"; "configurable/data/quantity_and_stock_status/qty"; "configurable/data/quantity_and_stock_status/is_in_stock"; "configurable/data/visibility"; "constraint"; "configurable/data/price/preset";"configurable/data/configurable_attributes_data/preset";
+"Configurable %isolation%"; "conf_sku_%isolation%";"100";"1";"-";"-";"-"; "assertProductSaveMessage, assertConfigurableInGrid, assertConfigurableInCategory, assertConfigurableView, assertConfigurableInCart";"MAGETWO-23062";"default";
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..85ffc1b1ff4ebc6c8396f50dd2a05686bb53e646
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInCmsPageForm.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\Constraint;
+
+use Magento\Cms\Test\Page\Adminhtml\CmsNew;
+use Magento\Core\Test\Fixture\SystemVariable;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertSystemVariableNotInCmsPageForm
+ */
+class AssertSystemVariableNotInCmsPageForm extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that custom system variable not in cms page form
+     *
+     * @param CmsNew $cmsNewPage
+     * @param SystemVariable $systemVariable
+     * @return void
+     */
+    public function processAssert(
+        CmsNew $cmsNewPage,
+        SystemVariable $systemVariable
+    ) {
+        $customVariableName = $systemVariable->getName();
+        $cmsNewPage->open();
+        $cmsPageForm = $cmsNewPage->getPageForm();
+        $variables = $cmsPageForm->getSystemVariables();
+
+        \PHPUnit_Framework_Assert::assertFalse(
+            in_array($customVariableName, $variables),
+            'Custom System Variable "' . $customVariableName . '" is present in Cms Page Form.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return "Custom System Variable is absent in Cms Page Form.";
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php
new file mode 100644
index 0000000000000000000000000000000000000000..a8f89116f609881c56a297c335afabef573b3c4c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableNotInGrid.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\Constraint;
+
+use Magento\Core\Test\Fixture\SystemVariable;
+use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertSystemVariableNotInGrid
+ */
+class AssertSystemVariableNotInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert Custom System Variable not available in System Variable grid
+     *
+     * @param SystemVariableIndex $systemVariableIndexNew
+     * @param SystemVariable $systemVariable
+     * @return void
+     */
+    public function processAssert(
+        SystemVariableIndex $systemVariableIndexNew,
+        SystemVariable $systemVariable
+    ) {
+        $filter = [
+            'code' => $systemVariable->getCode(),
+            'name' => $systemVariable->getName(),
+        ];
+
+        $systemVariableIndexNew->open();
+        \PHPUnit_Framework_Assert::assertFalse(
+            $systemVariableIndexNew->getSystemVariableGrid()->isRowVisible($filter),
+            'Custom System Variable with code \'' . $filter['code'] . '\' is present in System Variable grid.'
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Custom System Variable is absent in grid.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c5d294676d44294ec5d27dff6848864c3a43623
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Constraint/AssertSystemVariableSuccessDeleteMessage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\Constraint;
+
+use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertSystemVariableSuccessDeleteMessage
+ */
+class AssertSystemVariableSuccessDeleteMessage extends AbstractConstraint
+{
+    const SUCCESS_DELETE_MESSAGE = 'You deleted the custom variable.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that success delete message is correct after Custom System Variable deleted
+     *
+     * @param SystemVariableIndex $systemVariableIndexPage
+     * @return void
+     */
+    public function processAssert(SystemVariableIndex $systemVariableIndexPage)
+    {
+        $actualMessage = $systemVariableIndexPage->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_DELETE_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_DELETE_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Returns a string representation of successful assertion
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Custom System Variable success delete message is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.php b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..276eeabd3975bcb016d0315cc2791c8acbebd73f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.php
@@ -0,0 +1,80 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class SystemVariableIndex
+ */
+class SystemVariableIndex extends BackendPage
+{
+    const MCA = 'admin/system_variable/index';
+
+    protected $_blocks = [
+        'gridPageActions' => [
+            'name' => 'gridPageActions',
+            'class' => 'Magento\Backend\Test\Block\GridPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'systemVariableGrid' => [
+            'name' => 'systemVariableGrid',
+            'class' => 'Magento\Backend\Test\Block\System\Variable\Grid',
+            'locator' => '#customVariablesGrid',
+            'strategy' => 'css selector',
+        ],
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\GridPageActions
+     */
+    public function getGridPageActions()
+    {
+        return $this->getBlockInstance('gridPageActions');
+    }
+
+    /**
+     * @return \Magento\Backend\Test\Block\System\Variable\Grid
+     */
+    public function getSystemVariableGrid()
+    {
+        return $this->getBlockInstance('systemVariableGrid');
+    }
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.xml b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f4d539269c9d29ef3f789e9c29b203df277581f1
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableIndex.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="admin/system_variable/index" >
+    <block>
+        <name>gridPageActions</name>
+        <class>Magento\Backend\Test\Block\GridPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>systemVariableGrid</name>
+        <class>Magento\Backend\Test\Block\System\Variable\Grid</class>
+        <locator>#customVariablesGrid</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php
new file mode 100644
index 0000000000000000000000000000000000000000..df051f7158a5f6af7e98427913c3f9229b4d3078
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class SystemVariableNew
+ */
+class SystemVariableNew extends BackendPage
+{
+    const MCA = 'admin/system_variable/new';
+
+    protected $_blocks = [
+        'formPageActions' => [
+            'name' => 'formPageActions',
+            'class' => 'Magento\Backend\Test\Block\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'systemVariableForm' => [
+            'name' => 'systemVariableForm',
+            'class' => 'Magento\Backend\Test\Block\System\Variable\Edit\VariableForm',
+            'locator' => '#edit_form',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Backend\Test\Block\FormPageActions
+     */
+    public function getFormPageActions()
+    {
+        return $this->getBlockInstance('formPageActions');
+    }
+
+    /**
+     * @return \Magento\Backend\Test\Block\System\Variable\Edit\VariableForm
+     */
+    public function getSystemVariableForm()
+    {
+        return $this->getBlockInstance('systemVariableForm');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a2dac6b6b79862c0016b634971b5f56acbe310c9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/Page/Adminhtml/SystemVariableNew.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="admin/system_variable/new" >
+    <block>
+        <name>formPageActions</name>
+        <class>Magento\Backend\Test\Block\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>systemVariableForm</name>
+        <class>Magento\Backend\Test\Block\System\Variable\Edit\VariableForm</class>
+        <locator>#edit_form</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..45623cb81a7258a5a750ee0a18649f48f825baa4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Core\Test\TestCase;
+
+use Magento\Core\Test\Fixture\SystemVariable;
+use Magento\Core\Test\Page\Adminhtml\SystemVariableIndex;
+use Magento\Core\Test\Page\Adminhtml\SystemVariableNew;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for DeleteSystemVariableEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. Custom Variable is created
+ *
+ * Steps:
+ * 1. Login to backend.
+ * 2. Navigate to System->Other Settings->Custom Variables.
+ * 3. Open Variable.
+ * 4. Click 'Delete' button.
+ * 5. Perform asserts.
+ *
+ * @group Variables_(PS)
+ * @ZephyrId MAGETWO-25535
+ */
+class DeleteSystemVariableEntityTest extends Injectable
+{
+    /**
+     * Custom System Variable grid page
+     *
+     * @var SystemVariableIndex
+     */
+    protected $systemVariableIndexPage;
+
+    /**
+     * Custom System Variable new and edit page
+     *
+     * @var SystemVariableNew
+     */
+    protected $systemVariableNewPage;
+
+    /**
+     * Injection data
+     *
+     * @param SystemVariableIndex $systemVariableIndex
+     * @param SystemVariableNew $systemVariableNew
+     * @return void
+     */
+    public function __inject(
+        SystemVariableIndex $systemVariableIndex,
+        SystemVariableNew $systemVariableNew
+    ) {
+        $this->systemVariableIndexPage = $systemVariableIndex;
+        $this->systemVariableNewPage = $systemVariableNew;
+    }
+
+    /**
+     * Delete Custom System Variable Entity test
+     *
+     * @param SystemVariable $systemVariable
+     * @return void
+     */
+    public function test(SystemVariable $systemVariable)
+    {
+        // Precondition
+        $systemVariable->persist();
+
+        // Steps
+        $filter = [
+            'code' => $systemVariable->getCode(),
+            'name' => $systemVariable->getName(),
+        ];
+        $this->systemVariableIndexPage->open();
+        $this->systemVariableIndexPage->getSystemVariableGrid()->searchAndOpen($filter);
+        $this->systemVariableNewPage->getFormPageActions()->delete();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ec58eb1c03c37c8e376808908bf5a05ddc013dad
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/TestCase/DeleteSystemVariableEntityTest/test.csv
@@ -0,0 +1,2 @@
+"constraint"
+"assertSystemVariableSuccessDeleteMessage, assertSystemVariableNotInGrid, assertSystemVariableNotInCmsPageForm"
\ No newline at end of file
diff --git a/app/code/Magento/CatalogInventory/etc/indexers.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml
similarity index 77%
rename from app/code/Magento/CatalogInventory/etc/indexers.xml
rename to dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml
index 448e36b0beaf376d6098a7f2e73daf0c06ed1fa6..7fb1490cff2005d37ea423e31772c710f5898827 100644
--- a/app/code/Magento/CatalogInventory/etc/indexers.xml
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/curl/di.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" ?>
 <!--
 /**
  * Magento
@@ -23,9 +23,6 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Index/etc/indexers.xsd">
-    <indexer name="cataloginventory_stock" instance="Magento\CatalogInventory\Model\Indexer\Stock" />
-    <indexer name="catalog_product_attribute">
-        <depends name="cataloginventory_stock" />
-    </indexer>
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="\Magento\Core\Test\Handler\SystemVariable\SystemVariableInterface" type="\Magento\Core\Test\Handler\SystemVariable\Curl" />
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ff54ee59660a7f033945d96293f1ba66138f6047
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/constraint.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<constraint>
+    <assertSystemVariableSuccessDeleteMessage module="Magento_Core">
+        <severeness>low</severeness>
+    </assertSystemVariableSuccessDeleteMessage>
+    <assertSystemVariableNotInGrid module="Magento_Core">
+        <severeness>low</severeness>
+    </assertSystemVariableNotInGrid>
+    <assertSystemVariableNotInCmsPageForm module="Magento_Core">
+        <severeness>low</severeness>
+    </assertSystemVariableNotInCmsPageForm>
+</constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b71f00f7be2a3de3d9b324638e455a1a2709ae1c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/fixture.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture>
+    <systemVariable module="Magento_Core">
+        <type>composite</type>
+        <entities>
+            <core_variable>core_variable</core_variable>
+            <core_variable_value>core_variable_value</core_variable_value>
+        </entities>
+        <collection>Magento\Core\Model\Resource\Variable\Collection</collection>
+    </systemVariable>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/page.xml
new file mode 100644
index 0000000000000000000000000000000000000000..27087f9eaac3cbe4fcbc600f8706b15b4d9b4a7f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Core/Test/etc/global/page.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page>
+    <systemVariableIndex>
+        <mca>admin/system_variable/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Core\Test\Page\Adminhtml\SystemVariableIndex</class>
+    </systemVariableIndex>
+    <systemVariableNew>
+        <mca>admin/system_variable/new</mca>
+        <area>adminhtml</area>
+        <class>Magento\Core\Test\Page\Adminhtml\SystemVariableNew</class>
+    </systemVariableNew>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php
index 4af3002dd3d9efb7e433045eb973cb8dbccd1301..8194ce7e3e85aaa74be140c1c1bb1866db1bab72 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.php
@@ -24,10 +24,10 @@
 
 namespace Magento\Downloadable\Test\Fixture;
 
-use Mtf\Fixture\InjectableFixture;
 use Mtf\System\Config;
 use Mtf\Handler\HandlerFactory;
 use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\InjectableFixture;
 use Mtf\Repository\RepositoryFactory;
 use Mtf\System\Event\EventManagerInterface;
 
@@ -89,7 +89,6 @@ class CatalogProductDownloadable extends InjectableFixture
         if (!isset($this->data['url_key']) && isset($this->data['name'])) {
             $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-');
         }
-
     }
 
     protected $dataConfig = [
@@ -107,8 +106,10 @@ class CatalogProductDownloadable extends InjectableFixture
         'tax_class_id' => ['dataSet' => 'Taxable Goods'],
         'description' => 'This is description for downloadable product',
         'short_description' => 'This is short description for downloadable product',
-        'quantity_and_stock_status_qty' => '1',
-        'quantity_and_stock_status' => 'In Stock',
+        'quantity_and_stock_status' => [
+            'qty' => 1.0000,
+            'is_in_stock' => 'In Stock',
+        ],
         'is_virtual' => 'Yes',
         'downloadable_links' => ['preset' => 'default'],
     ];
@@ -396,7 +397,7 @@ class CatalogProductDownloadable extends InjectableFixture
     ];
 
     protected $stock_data_min_qty = [
-        'attribute_code' => 'stock_data_min_qty',
+        'attribute_code' => 'stock_data',
         'input' => 'text',
         'group' => 'advanced-inventory',
     ];
@@ -422,15 +423,6 @@ class CatalogProductDownloadable extends InjectableFixture
         'group' => 'product-details',
     ];
 
-    protected $qty = [
-        'attribute_code' => 'qty',
-        'backend_type' => 'int',
-        'is_required' => '0',
-        'default_value' => '1',
-        'input' => 'text',
-        'group' => 'product-details',
-    ];
-
     protected $related_tgtr_position_behavior = [
         'attribute_code' => 'related_tgtr_position_behavior',
         'backend_type' => 'int',
@@ -649,7 +641,7 @@ class CatalogProductDownloadable extends InjectableFixture
         'is_required' => '0',
         'default_value' => '',
         'input' => 'weight',
-        'group' => 'product-details',
+        'group' => 'product-details'
     ];
 
     protected $custom_options = [
@@ -658,7 +650,7 @@ class CatalogProductDownloadable extends InjectableFixture
         'is_required' => '0',
         'default_value' => 'default',
         'group' => 'customer-options',
-        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CustomOptions'
     ];
 
     protected $id = [
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml
index bf08f36eef6985833150be34836355ebce953652..34b7746109a689b15c2c8c87b8d062ee4669f6aa 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable.xml
@@ -262,13 +262,6 @@
             <default_value></default_value>
             <input>price</input>
         </price>
-        <qty>
-            <attribute_code>quantity_and_stock_status][qty</attribute_code>
-            <backend_type>int</backend_type>
-            <is_required>0</is_required>
-            <default_value>1</default_value>
-            <input>select</input>
-        </qty>
         <related_tgtr_position_behavior>
             <attribute_code>related_tgtr_position_behavior</attribute_code>
             <backend_type>int</backend_type>
@@ -357,6 +350,8 @@
             <backend_type>int</backend_type>
             <is_required>0</is_required>
             <default_value>2</default_value>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\TaxClass</source>
+            <group>product-details</group>
             <input>select</input>
         </tax_class_id>
         <thumbnail>
@@ -473,7 +468,5 @@
         <input_prefix>product</input_prefix>
     </data_config>
     <repository_class>Magento\Downloadable\Test\Repository\CatalogProductDownloadable</repository_class>
-    <handler_interface>
-        Magento\Downloadable\Test\Handler\CatalogProductDownloadable\CatalogProductDownloadableInterface
-    </handler_interface>
+    <handler_interface>Magento\Downloadable\Test\Handler\CatalogProductDownloadable\CatalogProductDownloadableInterface</handler_interface>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php
index fc54c7530556d0e80b38c82abb3ddd42faf4e561..5015ced85080d367c9c82de931b6603621d5c8b8 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Links.php
@@ -33,6 +33,20 @@ use Mtf\Fixture\FixtureInterface;
  */
 class Links implements FixtureInterface
 {
+    /**
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
     /**
      * Construct for class
      *
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php
index b060900fa409904a6dbeee8ffa01cd2e215924b2..bb890670a923ce48251a5cb6e696456035c9732e 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Fixture/CatalogProductDownloadable/Samples.php
@@ -28,11 +28,24 @@ use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class Samples
- *
  * Preset for sample block
  */
 class Samples implements FixtureInterface
 {
+    /**
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
     /**
      * Construct for class
      *
@@ -134,9 +147,11 @@ class Samples implements FixtureInterface
                 ]
             ]
         ];
+
         if (!isset($presets[$name])) {
             return null;
         }
+
         return $presets[$name];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php
index 443a6e013030a0e965d3a3691487e6bd5ddeb9bf..ca5aead81bec4fcdbd4acdd85037a61be6cdcaa7 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Handler/CatalogProductDownloadable/Curl.php
@@ -24,43 +24,25 @@
 
 namespace Magento\Downloadable\Test\Handler\CatalogProductDownloadable;
 
+use Mtf\System\Config;
 use Mtf\Fixture\FixtureInterface;
-use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as AbstractCurl;
+use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as ProductCurl;
 
 /**
  * Class Curl
  * Create new downloadable product via curl
  */
-class Curl extends AbstractCurl implements CatalogProductDownloadableInterface
+class Curl extends ProductCurl implements CatalogProductDownloadableInterface
 {
     /**
-     * Post request for creating downloadable product
+     * Constructor
      *
-     * @param FixtureInterface $fixture [optional]
-     * @return array
+     * @param Config $configuration
      */
-    public function persist(FixtureInterface $fixture = null)
+    public function __construct(Config $configuration)
     {
-        $this->extendPlaceholder();
-        $config = $fixture->getDataConfig();
-        $prefix = isset($config['input_prefix']) ? $config['input_prefix'] : null;
-        $data = $this->prepareData($fixture, $prefix);
-
-        if ($prefix) {
-            $data['downloadable'] = $data[$prefix]['downloadable'];
-            unset($data[$prefix]['downloadable']);
-        }
-
-        return ['id' => $this->createProduct($data, $config)];
-    }
+        parent::__construct($configuration);
 
-    /**
-     * Expand basic placeholder
-     *
-     * @return void
-     */
-    protected function extendPlaceholder()
-    {
         $this->mappingData += [
             'links_purchased_separately' => [
                 'Yes' => 1,
@@ -73,4 +55,22 @@ class Curl extends AbstractCurl implements CatalogProductDownloadableInterface
             ],
         ];
     }
+
+    /**
+     * Prepare POST data for creating product request
+     *
+     * @param FixtureInterface $fixture
+     * @param string|null $prefix [optional]
+     * @return array
+     */
+    protected function prepareData(FixtureInterface $fixture, $prefix = null)
+    {
+        $data = parent::prepareData($fixture, null);
+        $downloadable = $data['downloadable'];
+        unset($data['downloadable']);
+        $data = $prefix ? [$prefix => $data] : $data;
+        $data['downloadable'] = $downloadable;
+
+        return $this->replaceMappingData($data);
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php
index 5d82c6fce0215d7935920583ebfd227ffe85ef8a..e13fb5242c35889f0964e68c861cd71404677e75 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/CatalogProductDownloadable.php
@@ -21,6 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Downloadable\Test\Repository;
 
 use Mtf\Repository\AbstractRepository;
@@ -32,9 +33,10 @@ use Mtf\Repository\AbstractRepository;
 class CatalogProductDownloadable extends AbstractRepository
 {
     /**
-     * @constructor
-     * @param array $defaultConfig
-     * @param array $defaultData
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
@@ -45,15 +47,19 @@ class CatalogProductDownloadable extends AbstractRepository
             'sku' => 'sku_test_downloadable_product_%isolation%',
             'price' => 280.00,
             'type_id' => 'downloadable',
-            'tax_class' => ['Taxable Goods'],
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
             'quantity_and_stock_status' => [
                 'qty' => 90.0000,
                 'is_in_stock' => 'In Stock',
             ],
             'status' => 'Product online',
-            'category_ids' => ['presets' => 'default_subcategory'],
             'visibility' => 'Catalog, Search',
             'url_key' => 'test-downloadable-product-%isolation%',
+            'stock_data' => [
+                'manage_stock' => 'Yes',
+                'qty' => 90.0000,
+                'is_in_stock' => 'Yes'
+            ],
             'is_virtual' => 'Yes',
             'links_title' => 'Links',
             'links_purchased_separately' => 'Yes',
@@ -62,7 +68,7 @@ class CatalogProductDownloadable extends AbstractRepository
                     [
                         'title' => 'Link title',
                         'price' => '1',
-                        'number_of_downloads' => '1',
+                        'number_of_downloads' => 1,
                         'is_shareable' => 'Use config',
                         'sample' => [
                             'type' => 'url',
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.php b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.php
index c44e880f6a28b3b9b076ffd19073d27c7afe5128..c41854cf2cd2f97752832753f86774ab7ef6aa2d 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.php
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/Repository/DownloadableProduct.php
@@ -21,10 +21,15 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Downloadable\Test\Repository;
 
 use Magento\Catalog\Test\Repository\Product;
 
+/**
+ * Class DownloadableProduct
+ */
 class DownloadableProduct extends Product
 {
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
index 219b5b0a909ee79abc3846760a7730e63b38f94e..19443badf94798f2c292c5fd8ea942adcbd1dcd6 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/CreateDownloadableProductEntityTest/testCreateDownloadableProduct.csv
@@ -1,4 +1,4 @@
-product/data/name;product/data/sku;product/data/price;product/data/tax_class_id/dataSet;product/data/qty;product/data/quantity_and_stock_status;product/data/is_virtual;product/data/category;product/data/description;product/data/short_description;product/data/inventory_manage_stock;product/data/inventory_qty;product/data/stock_data_use_config_min_qty;product/data/stock_data_min_qty;product/data/downloadable_sample/preset;product/data/downloadable_links/preset;product/data/custom_options/preset;product/data/special_price;product/data/group_price/preset;product/data/tier_price/preset;constraint
+product/data/name;product/data/sku;product/data/price;product/data/tax_class_id/dataSet;product/data/quantity_and_stock_status/qty;product/data/quantity_and_stock_status/is_in_stock;product/data/is_virtual;product/data/category;product/data/description;product/data/short_description;product/data/inventory_manage_stock;product/data/inventory_qty;product/data/stock_data_use_config_min_qty;product/data/stock_data_min_qty;product/data/downloadable_sample/preset;product/data/downloadable_links/preset;product/data/custom_options/preset;product/data/special_price;product/data/group_price/preset;product/data/tier_price/preset;constraint
 DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;100;Taxable Goods;1;In Stock;Yes;Default Category;-;-;-;-;-;-;-;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertProductPage, assertProductInStock
 DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;1;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;default;default;-;-;-;-;assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductVisibleInCategory, assertDownloadableSamplesData, assertDownloadableLinksData
 DownloadableProduct_%isolation%;DownloadableProduct_%isolation%;33;Taxable Goods;10;In Stock;Yes;category %isolation%;-;-;-;-;-;-;-;default;default;-;-;-;assertProductSaveMessage, assertDownloadableProductForm, assertCustomOptionsOnProductPage, assertProductVisibleInCategory, assertProductPage, assertDownloadableLinksData
diff --git a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv
index c93d36d0c73110a1b042f02216b33d85530db283..dad29f9cefecde208aaf75546ec68253d650d9dc 100644
--- a/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv
+++ b/dev/tests/functional/tests/app/Magento/Downloadable/Test/TestCase/UpdateDownloadableProductEntityTest/testUpdateDownloadableProduct.csv
@@ -1,4 +1,4 @@
-"product/data/name";"product/data/sku";"product/data/price";"product/data/tax_class_id/dataSet";"product/data/qty";"product/data/quantity_and_stock_status";"product/data/is_virtual";"product/data/weight";"product/data/category";"product/data/description";"product/data/short_description";"product/data/inventory_manage_stock";"product/data/inventory_qty";"product/data/stock_data_use_config_min_qty";"product/data/stock_data_min_qty";"product/data/downloadable_sample/preset";"product/data/downloadable_links/preset";"product/data/custom_options/preset";"product/data/special_price";"isRequired";"constraint"
+"product/data/name";"product/data/sku";"product/data/price";"product/data/tax_class_id/dataSet";"product/data/quantity_and_stock_status/qty";"product/data/quantity_and_stock_status/is_in_stock";"product/data/is_virtual";"product/data/weight";"product/data/category";"product/data/description";"product/data/short_description";"product/data/inventory_manage_stock";"product/data/inventory_qty";"product/data/stock_data_use_config_min_qty";"product/data/stock_data_min_qty";"product/data/downloadable_sample/preset";"product/data/downloadable_links/preset";"product/data/custom_options/preset";"product/data/special_price";"isRequired";"constraint"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"55";"Taxable Goods";"10";"In Stock";"Yes";"-";"-";"-";"-";"-";"-";"-";"-";"with_three_samples";"with_three_links";"two_options";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductPage, assertDownloadableLinksData, assertProductInStock, assertCustomOptionsOnProductPage, assertProductSearchableBySku"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"100";"Taxable Goods";"50";"Out of Stock";"Yes";"-";"Default Category";"-";"-";"-";"-";"-";"-";"-";"default";"-";"-";"No";"assertProductSaveMessage, assertProductOutOfStock, assertProductInGrid, assertDownloadableProductForm"
 "DownloadableProduct_%isolation%";"DownloadableProduct_%isolation%";"9999";"Taxable Goods";"123";"-";"Yes";"-";"Default Category";"-";"-";"Yes";"-";"No";"123";"-";"-";"-";"-";"No";"assertProductSaveMessage, assertProductInGrid, assertDownloadableProductForm, assertProductOutOfStock"
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php
new file mode 100644
index 0000000000000000000000000000000000000000..7944dfd15aa15c6a232fb517336e56c215e09a5e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.php
@@ -0,0 +1,732 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Test\Fixture;
+
+use Mtf\System\Config;
+use Mtf\Handler\HandlerFactory;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\InjectableFixture;
+use Mtf\Repository\RepositoryFactory;
+use Mtf\System\Event\EventManagerInterface;
+
+/**
+ * Class CatalogProductGrouped
+ * Fixture for Grouped product
+ *
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.ExcessivePublicCount)
+ */
+class CatalogProductGrouped extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\GroupedProduct\Test\Repository\CatalogProductGrouped';
+
+    // @codingStandardsIgnoreStart
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\GroupedProduct\Test\Handler\CatalogProductGrouped\CatalogProductGroupedInterface';
+    // @codingStandardsIgnoreEnd
+
+    /**
+     * Constructor
+     *
+     * @constructor
+     * @param Config $configuration
+     * @param RepositoryFactory $repositoryFactory
+     * @param FixtureFactory $fixtureFactory
+     * @param HandlerFactory $handlerFactory
+     * @param EventManagerInterface $eventManager
+     * @param array $data
+     * @param string $dataSet
+     * @param bool $persist
+     */
+    public function __construct(
+        Config $configuration,
+        RepositoryFactory $repositoryFactory,
+        FixtureFactory $fixtureFactory,
+        HandlerFactory $handlerFactory,
+        EventManagerInterface $eventManager,
+        array $data = [],
+        $dataSet = '',
+        $persist = false
+    ) {
+        parent::__construct(
+            $configuration,
+            $repositoryFactory,
+            $fixtureFactory,
+            $handlerFactory,
+            $eventManager,
+            $data,
+            $dataSet,
+            $persist
+        );
+
+        if (!isset($this->data['url_key']) && isset($this->data['name'])) {
+            $this->data['url_key'] = trim(strtolower(preg_replace('#[^0-9a-z%]+#i', '-', $this->data['name'])), '-');
+        }
+
+    }
+
+    protected $dataConfig = [
+        'create_url_params' => [
+            'type' => 'grouped',
+            'set' => '4',
+        ],
+        'input_prefix' => 'product',
+    ];
+
+    protected $defaultDataSet = [
+        'name' => 'GroupedProduct_%isolation%',
+        'sku' => 'GroupedProduct_%isolation%',
+        'price' => '100',
+        'tax_class' => 'Taxable Goods',
+        'description' => 'This is description for grouped product',
+        'short_description' => 'This is short description for grouped product',
+        'quantity_and_stock_status' => [
+            'qty' => '1',
+            'is_in_stock' => 'In Stock'
+        ],
+    ];
+
+    protected $category_ids = [
+        'attribute_code' => 'category_ids',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\CategoryIds'
+    ];
+
+    protected $country_of_manufacture = [
+        'attribute_code' => 'country_of_manufacture',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $created_at = [
+        'attribute_code' => 'created_at',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $custom_design = [
+        'attribute_code' => 'custom_design',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $associated = [
+        'attribute_code' => 'associated',
+        'backend_type' => 'virtual',
+        'is_required' => '1',
+        'group' => 'grouped',
+        'source' => 'Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped\Associated',
+    ];
+
+    protected $custom_design_from = [
+        'attribute_code' => 'custom_design_from',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $custom_design_to = [
+        'attribute_code' => 'custom_design_to',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $custom_layout_update = [
+        'attribute_code' => 'custom_layout_update',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $description = [
+        'attribute_code' => 'description',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => '',
+        'group' => 'product-details'
+    ];
+
+    protected $gallery = [
+        'attribute_code' => 'gallery',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'gallery',
+    ];
+
+    protected $gift_message_available = [
+        'attribute_code' => 'gift_message_available',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $has_options = [
+        'attribute_code' => 'has_options',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $image = [
+        'attribute_code' => 'image',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $image_label = [
+        'attribute_code' => 'image_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $is_returnable = [
+        'attribute_code' => 'is_returnable',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '2',
+        'input' => 'select',
+    ];
+
+    protected $media_gallery = [
+        'attribute_code' => 'media_gallery',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'gallery',
+    ];
+
+    protected $meta_description = [
+        'attribute_code' => 'meta_description',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $meta_keyword = [
+        'attribute_code' => 'meta_keyword',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'textarea',
+    ];
+
+    protected $meta_title = [
+        'attribute_code' => 'meta_title',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $name = [
+        'attribute_code' => 'name',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'product-details'
+    ];
+
+    protected $news_from_date = [
+        'attribute_code' => 'news_from_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $news_to_date = [
+        'attribute_code' => 'news_to_date',
+        'backend_type' => 'datetime',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'date',
+    ];
+
+    protected $old_id = [
+        'attribute_code' => 'old_id',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $options_container = [
+        'attribute_code' => 'options_container',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => 'container2',
+        'input' => 'select',
+    ];
+
+    protected $page_layout = [
+        'attribute_code' => 'page_layout',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'select',
+    ];
+
+    protected $quantity_and_stock_status = [
+        'attribute_code' => 'quantity_and_stock_status',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'select',
+        'group' => 'product-details'
+
+    ];
+
+    protected $related_tgtr_position_behavior = [
+        'attribute_code' => 'related_tgtr_position_behavior',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $related_tgtr_position_limit = [
+        'attribute_code' => 'related_tgtr_position_limit',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $required_options = [
+        'attribute_code' => 'required_options',
+        'backend_type' => 'static',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $short_description = [
+        'attribute_code' => 'short_description',
+        'backend_type' => 'text',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => '',
+        'group' => 'autosettings'
+    ];
+
+    protected $sku = [
+        'attribute_code' => 'sku',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'product-details'
+    ];
+
+    protected $small_image = [
+        'attribute_code' => 'small_image',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $small_image_label = [
+        'attribute_code' => 'small_image_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $status = [
+        'attribute_code' => 'status',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '1',
+        'input' => 'select',
+    ];
+
+    protected $thumbnail = [
+        'attribute_code' => 'thumbnail',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'media_image',
+    ];
+
+    protected $thumbnail_label = [
+        'attribute_code' => 'thumbnail_label',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $updated_at = [
+        'attribute_code' => 'updated_at',
+        'backend_type' => 'static',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $upsell_tgtr_position_behavior = [
+        'attribute_code' => 'upsell_tgtr_position_behavior',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $upsell_tgtr_position_limit = [
+        'attribute_code' => 'upsell_tgtr_position_limit',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $url_key = [
+        'attribute_code' => 'url_key',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+        'group' => 'autosettings'
+    ];
+
+    protected $url_path = [
+        'attribute_code' => 'url_path',
+        'backend_type' => 'varchar',
+        'is_required' => '0',
+        'default_value' => '',
+        'input' => 'text',
+    ];
+
+    protected $visibility = [
+        'attribute_code' => 'visibility',
+        'backend_type' => 'int',
+        'is_required' => '0',
+        'default_value' => '4',
+        'input' => 'select',
+    ];
+
+    protected $id = [
+        'attribute_code' => 'id',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $type_id = [
+        'attribute_code' => 'type_id',
+        'backend_type' => 'virtual',
+    ];
+
+    protected $attribute_set_id = [
+        'attribute_code' => 'attribute_set_id',
+        'backend_type' => 'virtual',
+        'group' => 'product-details',
+        'source' => 'Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId',
+    ];
+
+    protected $website_ids = [
+        'attribute_code' => 'website_ids',
+        'backend_type' => 'virtual',
+        'default_value' => 'Main Website',
+    ];
+
+    public function getCategoryIds()
+    {
+        return $this->getData('category_ids');
+    }
+
+    public function getCountryOfManufacture()
+    {
+        return $this->getData('country_of_manufacture');
+    }
+
+    public function getCreatedAt()
+    {
+        return $this->getData('created_at');
+    }
+
+    public function getCustomDesign()
+    {
+        return $this->getData('custom_design');
+    }
+
+    public function getCustomDesignFrom()
+    {
+        return $this->getData('custom_design_from');
+    }
+
+    public function getCustomDesignTo()
+    {
+        return $this->getData('custom_design_to');
+    }
+
+    public function getCustomLayoutUpdate()
+    {
+        return $this->getData('custom_layout_update');
+    }
+
+    public function getDescription()
+    {
+        return $this->getData('description');
+    }
+
+    public function getGallery()
+    {
+        return $this->getData('gallery');
+    }
+
+    public function getGiftMessageAvailable()
+    {
+        return $this->getData('gift_message_available');
+    }
+
+    public function getHasOptions()
+    {
+        return $this->getData('has_options');
+    }
+
+    public function getImage()
+    {
+        return $this->getData('image');
+    }
+
+    public function getImageLabel()
+    {
+        return $this->getData('image_label');
+    }
+
+    public function getIsReturnable()
+    {
+        return $this->getData('is_returnable');
+    }
+
+    public function getMediaGallery()
+    {
+        return $this->getData('media_gallery');
+    }
+
+    public function getMetaDescription()
+    {
+        return $this->getData('meta_description');
+    }
+
+    public function getMetaKeyword()
+    {
+        return $this->getData('meta_keyword');
+    }
+
+    public function getMetaTitle()
+    {
+        return $this->getData('meta_title');
+    }
+
+    public function getName()
+    {
+        return $this->getData('name');
+    }
+
+    public function getNewsFromDate()
+    {
+        return $this->getData('news_from_date');
+    }
+
+    public function getNewsToDate()
+    {
+        return $this->getData('news_to_date');
+    }
+
+    public function getOldId()
+    {
+        return $this->getData('old_id');
+    }
+
+    public function getOptionsContainer()
+    {
+        return $this->getData('options_container');
+    }
+
+    public function getPageLayout()
+    {
+        return $this->getData('page_layout');
+    }
+
+    public function getQuantityAndStockStatus()
+    {
+        return $this->getData('quantity_and_stock_status');
+    }
+
+    public function getRelatedTgtrPositionBehavior()
+    {
+        return $this->getData('related_tgtr_position_behavior');
+    }
+
+    public function getRelatedTgtrPositionLimit()
+    {
+        return $this->getData('related_tgtr_position_limit');
+    }
+
+    public function getRequiredOptions()
+    {
+        return $this->getData('required_options');
+    }
+
+    public function getShortDescription()
+    {
+        return $this->getData('short_description');
+    }
+
+    public function getPrice()
+    {
+        return $this->getData('price');
+    }
+
+    public function getSpecialPrice()
+    {
+        return $this->getData('special_price');
+    }
+
+    public function getGroupPrice()
+    {
+        return $this->getData('group_price');
+    }
+
+    public function getTierPrice()
+    {
+        return $this->getData('tier_price');
+    }
+
+    public function getSku()
+    {
+        return $this->getData('sku');
+    }
+
+    public function getAssociated()
+    {
+        return $this->getData('associated');
+    }
+
+    public function getSmallImage()
+    {
+        return $this->getData('small_image');
+    }
+
+    public function getSmallImageLabel()
+    {
+        return $this->getData('small_image_label');
+    }
+
+    public function getStatus()
+    {
+        return $this->getData('status');
+    }
+
+    public function getThumbnail()
+    {
+        return $this->getData('thumbnail');
+    }
+
+    public function getThumbnailLabel()
+    {
+        return $this->getData('thumbnail_label');
+    }
+
+    public function getUpdatedAt()
+    {
+        return $this->getData('updated_at');
+    }
+
+    public function getUpsellTgtrPositionBehavior()
+    {
+        return $this->getData('upsell_tgtr_position_behavior');
+    }
+
+    public function getUpsellTgtrPositionLimit()
+    {
+        return $this->getData('upsell_tgtr_position_limit');
+    }
+
+    public function getUrlKey()
+    {
+        return $this->getData('url_key');
+    }
+
+    public function getUrlPath()
+    {
+        return $this->getData('url_path');
+    }
+
+    public function getVisibility()
+    {
+        return $this->getData('visibility');
+    }
+
+    public function getId()
+    {
+        return $this->getData('id');
+    }
+
+    public function getTypeId()
+    {
+        return $this->getData('type_id');
+    }
+
+    public function getAttributeSetId()
+    {
+        return $this->getData('attribute_set_id');
+    }
+
+    public function getWebsiteIds()
+    {
+        return $this->getData('website_ids');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml
new file mode 100644
index 0000000000000000000000000000000000000000..95e73b5137daf9676adcc83c527b5c9b5e66f461
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped.xml
@@ -0,0 +1,364 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Catalog\Test\Fixture\CatalogProductGrouped">
+    <module>Magento_Catalog</module>
+    <type>eav</type>
+    <entity_type>catalog_product</entity_type>
+    <product_type>grouped</product_type>
+    <collection>Magento\Catalog\Model\Resource\Product\Collection</collection>
+    <identifier>sku</identifier>
+    <fields>
+        <category_ids>
+            <attribute_code>category_ids</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </category_ids>
+        <country_of_manufacture>
+            <attribute_code>country_of_manufacture</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </country_of_manufacture>
+        <created_at>
+            <attribute_code>created_at</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </created_at>
+        <custom_design>
+            <attribute_code>custom_design</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </custom_design>
+        <custom_design_from>
+            <attribute_code>custom_design_from</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </custom_design_from>
+        <custom_design_to>
+            <attribute_code>custom_design_to</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </custom_design_to>
+        <custom_layout_update>
+            <attribute_code>custom_layout_update</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </custom_layout_update>
+        <description>
+            <attribute_code>description</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </description>
+        <gallery>
+            <attribute_code>gallery</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>gallery</input>
+        </gallery>
+        <gift_message_available>
+            <attribute_code>gift_message_available</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </gift_message_available>
+        <has_options>
+            <attribute_code>has_options</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </has_options>
+        <image>
+            <attribute_code>image</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </image>
+        <image_label>
+            <attribute_code>image_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </image_label>
+        <is_returnable>
+            <attribute_code>is_returnable</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>2</default_value>
+            <input>select</input>
+        </is_returnable>
+        <media_gallery>
+            <attribute_code>media_gallery</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>gallery</input>
+        </media_gallery>
+        <meta_description>
+            <attribute_code>meta_description</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </meta_description>
+        <meta_keyword>
+            <attribute_code>meta_keyword</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </meta_keyword>
+        <meta_title>
+            <attribute_code>meta_title</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </meta_title>
+        <name>
+            <attribute_code>name</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </name>
+        <news_from_date>
+            <attribute_code>news_from_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </news_from_date>
+        <news_to_date>
+            <attribute_code>news_to_date</attribute_code>
+            <backend_type>datetime</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>date</input>
+        </news_to_date>
+        <old_id>
+            <attribute_code>old_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </old_id>
+        <options_container>
+            <attribute_code>options_container</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value>container2</default_value>
+            <input>select</input>
+        </options_container>
+        <page_layout>
+            <attribute_code>page_layout</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>select</input>
+        </page_layout>
+        <quantity_and_stock_status>
+            <attribute_code>quantity_and_stock_status</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>1</default_value>
+            <input>select</input>
+        </quantity_and_stock_status>
+        <related_tgtr_position_behavior>
+            <attribute_code>related_tgtr_position_behavior</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </related_tgtr_position_behavior>
+        <related_tgtr_position_limit>
+            <attribute_code>related_tgtr_position_limit</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </related_tgtr_position_limit>
+        <required_options>
+            <attribute_code>required_options</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </required_options>
+        <short_description>
+            <attribute_code>short_description</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>textarea</input>
+        </short_description>
+        <sku>
+            <attribute_code>sku</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </sku>
+        <small_image>
+            <attribute_code>small_image</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </small_image>
+        <small_image_label>
+            <attribute_code>small_image_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </small_image_label>
+        <status>
+            <attribute_code>status</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>1</default_value>
+            <input>select</input>
+        </status>
+        <thumbnail>
+            <attribute_code>thumbnail</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>media_image</input>
+        </thumbnail>
+        <thumbnail_label>
+            <attribute_code>thumbnail_label</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </thumbnail_label>
+        <updated_at>
+            <attribute_code>updated_at</attribute_code>
+            <backend_type>static</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </updated_at>
+        <upsell_tgtr_position_behavior>
+            <attribute_code>upsell_tgtr_position_behavior</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </upsell_tgtr_position_behavior>
+        <upsell_tgtr_position_limit>
+            <attribute_code>upsell_tgtr_position_limit</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </upsell_tgtr_position_limit>
+        <url_key>
+            <attribute_code>url_key</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </url_key>
+        <url_path>
+            <attribute_code>url_path</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>0</is_required>
+            <default_value></default_value>
+            <input>text</input>
+        </url_path>
+        <visibility>
+            <attribute_code>visibility</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required>0</is_required>
+            <default_value>4</default_value>
+            <input>select</input>
+        </visibility>
+        <id>
+            <attribute_code>id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </id>
+        <associated>
+            <attribute_code>associated</attribute_code>
+            <backend_type>virtual</backend_type>
+            <group>grouped</group>
+            <is_required>1</is_required>
+            <source>Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped\GroupedProducts</source>
+        </associated>
+        <type_id>
+            <attribute_code>type_id</attribute_code>
+            <backend_type>virtual</backend_type>
+        </type_id>
+        <attribute_set_id>
+            <attribute_code>attribute_set_id</attribute_code>
+            <source>Magento\Catalog\Test\Fixture\CatalogProductSimple\AttributeSetId</source>
+            <backend_type>virtual</backend_type>
+            <group>product-details</group>
+        </attribute_set_id>
+        <website_ids>
+            <attribute_code>website_ids</attribute_code>
+            <backend_type>virtual</backend_type>
+            <default_value>Main Website</default_value>
+        </website_ids>
+    </fields>
+    <data_set>
+        <sku></sku>
+        <name></name>
+        <short_description></short_description>
+        <description></description>
+        <tax_class_id></tax_class_id>
+    </data_set>
+    <data_config>
+        <create_url_params>
+            <type>grouped</type>
+            <set>4</set>
+        </create_url_params>
+        <input_prefix>product</input_prefix>
+    </data_config>
+    <repository_class>Magento\Catalog\Test\Repository\CatalogProductGrouped</repository_class>
+    <handler_interface>Magento\Catalog\Test\Handler\CatalogProductGrouped\CatalogProductGroupedInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php
new file mode 100644
index 0000000000000000000000000000000000000000..7f6acc8d1d50a6bac93a87bdf7c41f2b9e3abb09
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Fixture/CatalogProductGrouped/Associated.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Test\Fixture\CatalogProductGrouped;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class Associated
+ * Grouped selections preset
+ */
+class Associated implements FixtureInterface
+{
+    /**
+     * Prepared dataSet data
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Current preset
+     *
+     * @var string
+     */
+    protected $currentPreset;
+
+    /**
+     * Constructor
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @param array $data
+     * @param array $params [optional]
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $data, array $params = [])
+    {
+        $this->params = $params;
+
+        if ($data['preset']) {
+            $this->currentPreset = $data['preset'];
+            $this->data = $this->getPreset($this->currentPreset);
+        }
+
+        if (!empty($this->data['products'])) {
+            foreach ($this->data['products'] as $key => $product) {
+                list($fixture, $dataSet) = explode('::', $product);
+                /** @var $productFixture InjectableFixture */
+                $productFixture = $fixtureFactory->createByCode($fixture, ['dataSet' => $dataSet]);
+                if (!$productFixture->hasData('id')) {
+                    $productFixture->persist();
+                }
+
+                $this->data['products'][$key] = $productFixture;
+            }
+
+            $assignedProducts = & $this->data['assigned_products'];
+            foreach (array_keys($assignedProducts) as $key) {
+                $assignedProducts[$key]['id'] = $this->data['products'][$key]->getId();
+                $assignedProducts[$key]['position'] = $key + 1;
+            }
+        }
+    }
+
+    /**
+     * Persists prepared data into application
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string|null $key [optional]
+     * @return mixed
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return string
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Preset array
+     *
+     * @param string $name
+     * @return mixed|null
+     */
+    protected function getPreset($name)
+    {
+        $presets = [
+            'defaultSimpleProduct' => [
+                'assigned_products' => [
+                    [
+                        'id' => '%id%',
+                        'position' => '%position%',
+                        'qty' => 5
+                    ],
+                    [
+                        'id' => '%id%',
+                        'position' => '%position%',
+                        'qty' => 6
+                    ]
+                ],
+                'products' => [
+                    'catalogProductSimple::default',
+                    'catalogProductSimple::default'
+                ],
+            ],
+            'defaultVirtualProduct' => [
+                'assigned_products' => [
+                    [
+                        'id' => '%id%',
+                        'position' => '%position%',
+                        'qty' => 5
+                    ],
+                    [
+                        'id' => '%id%',
+                        'position' => '%position%',
+                        'qty' => 6
+                    ]
+                ],
+                'products' => [
+                    'catalogProductVirtual::default',
+                    'catalogProductVirtual::default'
+                ],
+            ]
+        ];
+
+        if (!isset($presets[$name])) {
+            return null;
+        }
+
+        return $presets[$name];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/CatalogProductGroupedInterface.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/CatalogProductGroupedInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..88fd5283d4d7e3b15c523a87cb5e7ce356686ed4
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/CatalogProductGroupedInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Test\Handler\CatalogProductGrouped;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface CatalogProductGroupedInterface
+ */
+interface CatalogProductGroupedInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/Curl.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/Curl.php
new file mode 100644
index 0000000000000000000000000000000000000000..800c541211b73c9a3dc46ce7cce672f5c413ab7f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Handler/CatalogProductGrouped/Curl.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Test\Handler\CatalogProductGrouped;
+
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Magento\Catalog\Test\Handler\CatalogProductSimple\Curl as AbstractCurl;
+
+/**
+ * Class Curl
+ * Create new grouped product via curl
+ */
+class Curl extends AbstractCurl implements CatalogProductGroupedInterface
+{
+    /**
+     * Prepare POST data for creating product request
+     *
+     * @param FixtureInterface $fixture
+     * @param string|null $prefix [optional]
+     * @return array
+     */
+    protected function prepareData(FixtureInterface $fixture, $prefix = null)
+    {
+        $data = parent::prepareData($fixture, null);
+
+        $assignedProducts = [];
+        if (!empty($data['associated'])) {
+            $assignedProducts = $data['associated']['assigned_products'];
+            unset($data['associated']);
+        }
+
+        $data = $prefix ? [$prefix => $data] : $data;
+        foreach ($assignedProducts as $item) {
+            $data['links']['associated'][$item['id']] = $item;
+        }
+
+        return $data;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php
new file mode 100644
index 0000000000000000000000000000000000000000..d97cbf8e1ce1aecbbc0af30ad2eeae4cd2944f99
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/Repository/CatalogProductGrouped.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\GroupedProduct\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class CatalogProductGrouped
+ * Data for creation Catalog Product Grouped
+ */
+class CatalogProductGrouped extends AbstractRepository
+{
+    /**
+     * Constructor
+     *
+     * @param array $defaultConfig [optional]
+     * @param array $defaultData [optional]
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['default'] = [
+            'name' => 'Test grouped product %isolation%',
+            'sku' => 'sku_test_grouped_product_%isolation%',
+            'price' => ['value' => 120.00],
+            'weight' => 30.0000,
+            'category_ids' => ['presets' => 'default'],
+            'associated' => ['preset' => 'defaultSimpleProduct'],
+            'status' => 'Product online',
+            'visibility' => 'Catalog, Search',
+            'tax_class_id' => ['dataSet' => 'Taxable Goods'],
+            'url_key' => 'test-grouped-product-%isolation%',
+            'quantity_and_stock_status' => [
+                'qty' => 666.0000,
+                'is_in_stock' => 'In Stock',
+            ],
+            'website_ids' => ['Main Website'],
+            'attribute_set_id' => ['dataSet' => 'default'],
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/curl/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..787da2ccf44a910b74a7fc1e07119f566a0534e5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/curl/di.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <preference for="Magento\GroupedProduct\Test\Handler\CatalogProductGrouped\CatalogProductGroupedInterface" type="\Magento\GroupedProduct\Test\Handler\CatalogProductGrouped\Curl" />
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml
new file mode 100644
index 0000000000000000000000000000000000000000..6e618562b008cc4c888516acca1a2637d2d5e672
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/GroupedProduct/Test/etc/global/fixture.xml
@@ -0,0 +1,62 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture>
+    <catalogProductGrouped module="Magento_GroupedProduct">
+        <type>eav</type>
+        <entity_type>catalog_product</entity_type>
+        <product_type>grouped</product_type>
+        <collection>Magento\GroupedProduct\Model\Resource\Product\Collection</collection>
+        <identifier>sku</identifier>
+        <fields>
+            <id>
+                <attribute_code>id</attribute_code>
+                <backend_type>virtual</backend_type>
+            </id>
+            <grouped_products>
+                <attribute_code>grouped_selections</attribute_code>
+                <backend_type>virtual</backend_type>
+                <is_required>1</is_required>
+                <group>grouped</group>
+                <fixture>Magento\GroupedProduct\Test\Fixture\Grouped\Selections</fixture>
+            </grouped_products>
+        </fields>
+        <data_set>
+            <sku />
+            <name />
+            <short_description />
+            <description />
+            <tax_class_id />
+            <quantity_and_stock_status />
+        </data_set>
+        <data_config>
+            <create_url_params>
+                <type>grouped</type>
+                <set>4</set>
+            </create_url_params>
+            <input_prefix>product</input_prefix>
+        </data_config>
+    </catalogProductGrouped>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/FormPageActions.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/FormPageActions.php
new file mode 100755
index 0000000000000000000000000000000000000000..861ab7c3bb5a8d073da1d25b801f1b69fe4e00c5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/FormPageActions.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Block\Adminhtml;
+
+use Magento\Backend\Test\Block\FormPageActions as AbstractFormPageActions;
+
+/**
+ * Class FormPageActions
+ * Page actions block of reviews edit page
+ */
+class FormPageActions extends AbstractFormPageActions
+{
+    /**
+     * "Save Review" button
+     *
+     * @var string
+     */
+    protected $saveButton = '#save_button';
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Grid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Grid.php
old mode 100644
new mode 100755
index 196ef845ef8e85ac9bbb4e3634abb76016ebd776..ef1eb3446522c7a359f88e78afbd62cfa4cfe3a8
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Grid.php
@@ -28,16 +28,18 @@ use Mtf\Client\Element;
 use Magento\Backend\Test\Block\Widget\Grid as GridAbstract;
 
 /**
+ * Class Grid
  * Reviews grid
- *
  */
 class Grid extends GridAbstract
 {
     /**
-     * {@inheritdoc}
+     * Filters array mapping
+     *
+     * @var array
      */
     protected $filters = array(
-        'id' => array(
+        'review_id' => array(
             'selector' => '#reviwGrid_filter_review_id',
         ),
         'title' => array(
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Edit/RatingForm.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Grid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Rating/Grid.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.php
old mode 100644
new mode 100755
similarity index 53%
rename from dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit.php
rename to dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.php
index d8b53356dbcf802e44f32ff757cf6f1edc03c3f9..62b3e18f9c0039f12842557ccd589e86bccb3250
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/Edit.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.php
@@ -24,16 +24,15 @@
 
 namespace Magento\Review\Test\Block\Adminhtml;
 
-use Mtf\Fixture\FixtureInterface;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
 use Magento\Backend\Test\Block\Widget\Form;
 
 /**
+ * Class Edit
  * Review edit form
- *
  */
-class Edit extends Form
+class ReviewForm extends Form
 {
     /**
      * Posted by field
@@ -54,7 +53,21 @@ class Edit extends Form
      *
      * @var string
      */
-    protected $saveButton = '[data-ui-id$=save-button]';
+    protected $saveButton = '[data-ui-id$=save-button-button]';
+
+    /**
+     * Selector for single rating
+     *
+     * @var string
+     */
+    protected $ratingByNumber = './/*[@id="detailed_rating"]//*[contains(@class,"field-rating")][%d]';
+
+    /**
+     * Selector for label of checked rating
+     *
+     * @var string
+     */
+    protected $checkedRating = 'input[id$="_%d"]:checked + label';
 
     /**
      * Get data from 'Posted By' field
@@ -77,11 +90,54 @@ class Edit extends Form
     }
 
     /**
-     * Approve review
+     * Set approve review
+     *
+     * @return void
      */
-    public function approveReview()
+    public function setApproveReview()
     {
         $this->_rootElement->find($this->status, Locator::SELECTOR_CSS, 'select')->setValue('Approved');
-        $this->save();
+    }
+
+    /**
+     * Get list ratings
+     *
+     * @return array
+     */
+    public function getRatings()
+    {
+        $ratings = [];
+
+        $count = 1;
+        $rating = $this->_rootElement->find(sprintf($this->ratingByNumber, $count), Locator::SELECTOR_XPATH);
+        while ($rating->isVisible()) {
+            $ratings[$count] = [
+                'title' => $rating->find('./label/span', Locator::SELECTOR_XPATH)->getText(),
+                'rating' => $this->getRatingVote($rating)
+            ];
+
+            ++$count;
+            $rating = $this->_rootElement->find(sprintf($this->ratingByNumber, $count), Locator::SELECTOR_XPATH);
+        }
+
+        return $ratings;
+    }
+
+    /**
+     * Get rating vote
+     *
+     * @param Element $rating
+     * @return int
+     */
+    protected function getRatingVote(Element $rating)
+    {
+        $ratingVote = 5;
+        $ratingVoteElement = $rating->find(sprintf($this->checkedRating, $ratingVote));
+        while (!$ratingVoteElement->isVisible() && $ratingVote) {
+            --$ratingVote;
+            $ratingVoteElement = $rating->find(sprintf($this->checkedRating, $ratingVote));
+        }
+
+        return $ratingVote;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml
new file mode 100755
index 0000000000000000000000000000000000000000..05f0774d009510f3dbb5ddb0d69417c765b03024
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Adminhtml/ReviewForm.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<mapping strict="0">
+    <fields>
+        <status_id>
+            <input>select</input>
+        </status_id>
+        <select_stores>
+            <selector>[name="select_stores[]"]</selector>
+            <input>multiselectgrouplist</input>
+        </select_stores>
+        <detail>
+            <input>textarea</input>
+        </detail>
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.php
old mode 100644
new mode 100755
index 1d92a000c30ac441962846d2c743fe94e8bc4606..e8eb25a20b607bb0bf35b31e3a4be2fd20c89b27
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.php
@@ -25,15 +25,17 @@
 namespace Magento\Review\Test\Block;
 
 use Magento\Review\Test\Fixture\Rating;
-use Mtf\Block\Form as BlockForm;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Mtf\Block\Form as AbstractForm;
 use Mtf\Client\Element;
 use Mtf\Client\Element\Locator;
+use Mtf\Fixture\FixtureInterface;
 
 /**
  * Class Form
- * Review form
+ * Review form on frontend
  */
-class Form extends BlockForm
+class Form extends AbstractForm
 {
     /**
      * Legend selector
@@ -56,8 +58,17 @@ class Form extends BlockForm
      */
     protected $rating = './/*[@id="%s_rating_label"]/..[contains(@class,"rating")]';
 
+    /**
+     * Selector for label of rating vote
+     *
+     * @var string
+     */
+    protected $ratingVoteLabel = './div[contains(@class,"vote")]/label[contains(@id,"_%d_label")]';
+
     /**
      * Submit review form
+     *
+     * @return void
      */
     public function submit()
     {
@@ -95,4 +106,49 @@ class Form extends BlockForm
     {
         return $this->_rootElement->find(sprintf($this->rating, $rating->getRatingCode()), Locator::SELECTOR_XPATH);
     }
+
+    /**
+     * Fill the review form
+     *
+     * @param FixtureInterface $review
+     * @param Element|null $element
+     * @return $this
+     */
+    public function fill(FixtureInterface $review, Element $element = null)
+    {
+        if ($review instanceof ReviewInjectable) {
+            $this->fillRatings($review);
+        }
+        parent::fill($review, $element);
+    }
+
+    /**
+     * Fill ratings on the review form
+     *
+     * @param ReviewInjectable $review
+     * @return void
+     */
+    protected function fillRatings(ReviewInjectable $review)
+    {
+        if (!$review->hasData('ratings')) {
+            return;
+        }
+
+        foreach ($review->getRatings() as $rating) {
+            $this->setRating($rating['title'], $rating['rating']);
+        }
+    }
+
+    /**
+     * Set rating vote by rating code
+     *
+     * @param string $ratingCode
+     * @param string $ratingVote
+     * @return void
+     */
+    protected function setRating($ratingCode, $ratingVote)
+    {
+        $rating = $this->_rootElement->find(sprintf($this->rating, $ratingCode), Locator::SELECTOR_XPATH);
+        $rating->find(sprintf($this->ratingVoteLabel, $ratingVote), Locator::SELECTOR_XPATH)->click();
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Form.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View/Summary.php b/dev/tests/functional/tests/app/Magento/Review/Test/Block/Product/View/Summary.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInGrid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInGrid.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInProductPage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInProductPage.php
old mode 100644
new mode 100755
index e54c451aab2fb63bd36cc8e2d5ac0efe2eaafadd..728efdd2a50f9570579656edcfe458b600a87130
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInProductPage.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingInProductPage.php
@@ -26,6 +26,7 @@ namespace Magento\Review\Test\Constraint;
 
 use Magento\Catalog\Test\Page\Product\CatalogProductView;
 use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Review\Test\Fixture\ReviewInjectable;
 use Magento\Review\Test\Fixture\Rating;
 use Mtf\Constraint\AbstractConstraint;
 
@@ -42,26 +43,29 @@ class AssertProductRatingInProductPage extends AbstractConstraint
     protected $severeness = 'middle';
 
     /**
-     * Assert that product rating is displayed on frontend on product review
+     * Assert that product rating is displayed on product review(frontend)
      *
      * @param CatalogProductView $catalogProductView
      * @param CatalogProductSimple $product
-     * @param Rating $productRating
+     * @param ReviewInjectable|null $review [optional]
+     * @param Rating|null $productRating [optional]
      * @return void
      */
     public function processAssert(
         CatalogProductView $catalogProductView,
         CatalogProductSimple $product,
-        Rating $productRating
+        ReviewInjectable $review = null,
+        Rating $productRating = null
     ) {
         $catalogProductView->init($product);
         $catalogProductView->open();
         $catalogProductView->getReviewSummaryBlock()->getAddReviewLink()->click();
 
+        $rating = $productRating ? $productRating : $review->getDataFieldConfig('ratings')['source']->getRatings()[0];
         $reviewForm = $catalogProductView->getReviewFormBlock();
         \PHPUnit_Framework_Assert::assertTrue(
-            $reviewForm->isVisibleRating($productRating),
-            'Product rating "' . $productRating->getRatingCode() . '" is not displayed.'
+            $reviewForm->isVisibleRating($rating),
+            'Product rating "' . $rating->getRatingCode() . '" is not displayed.'
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingNotInGrid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingNotInGrid.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingNotInProductPage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingNotInProductPage.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php
new file mode 100755
index 0000000000000000000000000000000000000000..aec069bf2e271ba2c2e7e682a29b71d5333d1a94
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingOnReviewPage.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Constraint;
+
+use Magento\Review\Test\Page\Adminhtml\ReviewIndex;
+use Magento\Review\Test\Page\Adminhtml\ReviewEdit;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Mtf\Constraint\AbstractAssertForm;
+
+/**
+ * Class AssertProductRatingOnReviewPage
+ */
+class AssertProductRatingOnReviewPage extends AbstractAssertForm
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'middle';
+
+    /**
+     * Assert that product rating is displayed on product review(backend)
+     *
+     * @param ReviewIndex $reviewIndex
+     * @param ReviewEdit $reviewEdit
+     * @param ReviewInjectable $review
+     * @param ReviewInjectable|null $reviewInitial [optional]
+     * @return void
+     */
+    public function processAssert(
+        ReviewIndex $reviewIndex,
+        ReviewEdit $reviewEdit,
+        ReviewInjectable $review,
+        ReviewInjectable $reviewInitial = null
+    ) {
+        $filter = ['title' => $review->getTitle()];
+
+        $reviewIndex->open();
+        $reviewIndex->getReviewGrid()->searchAndOpen($filter);
+
+        $ratingReview = array_replace(
+            ($reviewInitial && $reviewInitial->hasData('ratings')) ? $reviewInitial->getRatings() : [],
+            $review->hasData('ratings') ? $review->getRatings() : []
+        );
+        $ratingReview = $this->sortData($ratingReview, ['::title']);
+        $ratingForm = $reviewEdit->getReviewForm()->getRatings();
+        $ratingForm = $this->sortData($ratingForm, ['::title']);
+        $error = $this->verifyData($ratingReview, $ratingForm);
+        \PHPUnit_Framework_Assert::assertTrue(empty($error), $error);
+    }
+
+    /**
+     * Text success product rating is displayed on edit review page(backend)
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Product rating is displayed on edit review page(backend).';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingSuccessDeleteMessage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingSuccessDeleteMessage.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductRatingSuccessSaveMessage.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductReviewInGrid.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductReviewInGrid.php
new file mode 100755
index 0000000000000000000000000000000000000000..3c6fcaf5798f00f702c4a08fce5fec6e2705f9c9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertProductReviewInGrid.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Constraint;
+
+use Magento\Review\Test\Page\Adminhtml\ReviewIndex;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertProductReviewInGrid
+ */
+class AssertProductReviewInGrid extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert that review is displayed in grid
+     *
+     * @param ReviewIndex $reviewIndex
+     * @param ReviewInjectable $review
+     * @return void
+     */
+    public function processAssert(ReviewIndex $reviewIndex, ReviewInjectable $review)
+    {
+        $filter = ['title' => $review->getTitle()];
+
+        $reviewIndex->open();
+        \PHPUnit_Framework_Assert::assertTrue(
+            $reviewIndex->getReviewGrid()->isRowVisible($filter),
+            'Review with '
+            . 'title "' . $filter['title'] . '"'
+            . 'is absent in Review grid.'
+        );
+    }
+
+    /**
+     * Text success exist review in grid on product reviews tab
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Review is present in grid on product reviews tab.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewCreationSuccessMessage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewCreationSuccessMessage.php
new file mode 100755
index 0000000000000000000000000000000000000000..71cd3129fb1af40d70bda1546665d1a311f33cd9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewCreationSuccessMessage.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Constraint;
+
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertReviewCreationSuccessMessage
+ */
+class AssertReviewCreationSuccessMessage extends AbstractConstraint
+{
+    /**
+     * Text of success message after review created
+     */
+    const SUCCESS_MESSAGE = 'Your review has been accepted for moderation.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that success message is displayed after review created
+     *
+     * @param CatalogProductView $catalogProductView
+     * @return void
+     */
+    public function processAssert(CatalogProductView $catalogProductView)
+    {
+        $actualMessage = $catalogProductView->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Text success create message is displayed
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Review success create message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewSuccessSaveMessage.php b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewSuccessSaveMessage.php
new file mode 100755
index 0000000000000000000000000000000000000000..be420f8baf91e96e8dc8c44276d1f3174cf6a1d7
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Constraint/AssertReviewSuccessSaveMessage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Constraint;
+
+use Magento\Review\Test\Page\Adminhtml\ReviewIndex;
+use Mtf\Constraint\AbstractConstraint;
+
+/**
+ * Class AssertReviewSuccessSaveMessage
+ */
+class AssertReviewSuccessSaveMessage extends AbstractConstraint
+{
+    const SUCCESS_MESSAGE = 'You saved the review.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'high';
+
+    /**
+     * Assert that success message is displayed after review save
+     *
+     * @param ReviewIndex $reviewIndex
+     * @return void
+     */
+    public function processAssert(ReviewIndex $reviewIndex)
+    {
+        $actualMessage = $reviewIndex->getMessagesBlock()->getSuccessMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::SUCCESS_MESSAGE,
+            $actualMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::SUCCESS_MESSAGE
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Text success save message is displayed
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Review success save message is present.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.php b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.php
old mode 100644
new mode 100755
index 447987b294d0918079d680608ef0bc276336360b..f0fc374118181a1ca791890aba40202089e1e557
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.php
@@ -96,6 +96,12 @@ class Rating extends InjectableFixture
         'group' => 'rating_information',
     ];
 
+    protected $options = [
+        'attribute_code' => 'options',
+        'backend_type' => 'virtual',
+        'group' => 'rating_information',
+    ];
+
     public function getRatingId()
     {
         return $this->getData('rating_id');
@@ -125,4 +131,9 @@ class Rating extends InjectableFixture
     {
         return $this->getData('stores');
     }
+
+    public function getOptions()
+    {
+        return $this->getData('options');
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
old mode 100644
new mode 100755
index 66e261cf218ebfa17820bb7d4cbf39ff804f7a5a..546d811e5fc34b742866e1a4b700cbe1b9f8408f
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Rating.xml
@@ -73,6 +73,11 @@
             <backend_type>virtual</backend_type>
             <group>rating_information</group>
         </stores>
+        <options>
+            <attribute_code>options</attribute_code>
+            <backend_type>virtual</backend_type>
+            <group>rating_information</group>
+        </options>
     </fields>
     <repository_class>Magento\Review\Test\Repository\Rating</repository_class>
     <handler_interface>Magento\Review\Test\Handler\Rating\RatingInterface</handler_interface>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.php b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/Review.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.php b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.php
new file mode 100755
index 0000000000000000000000000000000000000000..369f801bf3f21a7539eecfff16cdd2f1b636534b
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.php
@@ -0,0 +1,219 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Fixture;
+
+use Mtf\Fixture\InjectableFixture;
+
+/**
+ * Class ReviewInjectable
+ * Product review fixture
+ */
+class ReviewInjectable extends InjectableFixture
+{
+    /**
+     * @var string
+     */
+    protected $repositoryClass = 'Magento\Review\Test\Repository\ReviewInjectable';
+
+    /**
+     * @var string
+     */
+    protected $handlerInterface = 'Magento\Review\Test\Handler\ReviewInjectable\ReviewInjectableInterface';
+
+    /**
+     * Default data
+     *
+     * @var array
+     */
+    protected $defaultDataSet = [
+        'status_id' => 'Approved',
+        'select_stores' => ['Main Website/Main Website Store/Default Store View'],
+        'nickname' =>  'Guest customer %isolation%',
+        'title' => 'Summary review %isolation%',
+        'detail' => 'Text review %isolation%',
+        'ratings' => [
+            1 => [
+                'dataSet' => 'visibleOnDefaultWebsite',
+                'rating' => 4
+            ]
+        ],
+        'entity_id' => ['dataSet' => 'catalogProductSimple::default']
+    ];
+
+    protected $review_id = [
+        'attribute_code' => 'review_id',
+        'backend_type' => 'bigint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $created_at = [
+        'attribute_code' => 'created_at',
+        'backend_type' => 'timestamp',
+        'is_required' => '',
+        'default_value' => 'CURRENT_TIMESTAMP',
+        'input' => '',
+    ];
+
+    protected $entity_id = [
+        'attribute_code' => 'entity_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+        'source' => 'Magento\Review\Test\Fixture\ReviewInjectable\EntityId'
+    ];
+
+    protected $entity_pk_value = [
+        'attribute_code' => 'entity_pk_value',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $status_id = [
+        'attribute_code' => 'status_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $detail_id = [
+        'attribute_code' => 'detail_id',
+        'backend_type' => 'bigint',
+        'is_required' => '1',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $store_id = [
+        'attribute_code' => 'store_id',
+        'backend_type' => 'smallint',
+        'is_required' => '',
+        'default_value' => '0',
+        'input' => '',
+    ];
+
+    protected $title = [
+        'attribute_code' => 'title',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $detail = [
+        'attribute_code' => 'detail',
+        'backend_type' => 'text',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $nickname = [
+        'attribute_code' => 'nickname',
+        'backend_type' => 'varchar',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $customer_id = [
+        'attribute_code' => 'customer_id',
+        'backend_type' => 'int',
+        'is_required' => '',
+        'default_value' => '',
+        'input' => '',
+    ];
+
+    protected $ratings = [
+        'attribute_code' => 'ratings',
+        'backend_type' => 'virtual',
+        'source' => 'Magento\Review\Test\Fixture\ReviewInjectable\Ratings',
+    ];
+
+    public function getReviewId()
+    {
+        return $this->getData('review_id');
+    }
+
+    public function getCreatedAt()
+    {
+        return $this->getData('created_at');
+    }
+
+    public function getEntityId()
+    {
+        return $this->getData('entity_id');
+    }
+
+    public function getEntityPkValue()
+    {
+        return $this->getData('entity_pk_value');
+    }
+
+    public function getStatusId()
+    {
+        return $this->getData('status_id');
+    }
+
+    public function getDetailId()
+    {
+        return $this->getData('detail_id');
+    }
+
+    public function getStoreId()
+    {
+        return $this->getData('store_id');
+    }
+
+    public function getTitle()
+    {
+        return $this->getData('title');
+    }
+
+    public function getDetail()
+    {
+        return $this->getData('detail');
+    }
+
+    public function getNickname()
+    {
+        return $this->getData('nickname');
+    }
+
+    public function getCustomerId()
+    {
+        return $this->getData('customer_id');
+    }
+
+    public function getRatings()
+    {
+        return $this->getData('ratings');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.xml
new file mode 100755
index 0000000000000000000000000000000000000000..e7b344b51a6c7259bd4e35266b9c91bf91135a19
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<fixture class="Magento\Review\Test\Fixture\ReviewInjectable">
+    <module>Magento_Review</module>
+    <type>composite</type>
+    <entities>
+        <review>review</review>
+        <review_detail>review_detail</review_detail>
+    </entities>
+    <collection>Magento\Review\Model\Resource\Review\Collection</collection>
+    <fields>
+        <review_id>
+            <attribute_code>review_id</attribute_code>
+            <backend_type>bigint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </review_id>
+        <created_at>
+            <attribute_code>created_at</attribute_code>
+            <backend_type>timestamp</backend_type>
+            <is_required></is_required>
+            <default_value>CURRENT_TIMESTAMP</default_value>
+            <input></input>
+        </created_at>
+        <entity_id>
+            <attribute_code>entity_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+            <source>Magento\Review\Test\Fixture\ReviewInjectable\EntityId</source>
+        </entity_id>
+        <entity_pk_value>
+            <attribute_code>entity_pk_value</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </entity_pk_value>
+        <status_id>
+            <attribute_code>status_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </status_id>
+        <detail_id>
+            <attribute_code>detail_id</attribute_code>
+            <backend_type>bigint</backend_type>
+            <is_required>1</is_required>
+            <default_value></default_value>
+            <input></input>
+        </detail_id>
+        <store_id>
+            <attribute_code>store_id</attribute_code>
+            <backend_type>smallint</backend_type>
+            <is_required></is_required>
+            <default_value>0</default_value>
+            <input></input>
+        </store_id>
+        <title>
+            <attribute_code>title</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </title>
+        <detail>
+            <attribute_code>detail</attribute_code>
+            <backend_type>text</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </detail>
+        <nickname>
+            <attribute_code>nickname</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </nickname>
+        <customer_id>
+            <attribute_code>customer_id</attribute_code>
+            <backend_type>int</backend_type>
+            <is_required></is_required>
+            <default_value></default_value>
+            <input></input>
+        </customer_id>
+        <ratings>
+            <attribute_code>ratings</attribute_code>
+            <backend_type>virtual</backend_type>
+            <source>Magento\Review\Test\Fixture\ReviewInjectable\Ratings</source>
+        </ratings>
+    </fields>
+    <repository_class>Magento\Review\Test\Repository\ReviewInjectable</repository_class>
+    <handler_interface>Magento\Review\Test\Handler\ReviewInjectable\ReviewInjectableInterface</handler_interface>
+</fixture>
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/AttributeOptions.php b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/EntityId.php
old mode 100644
new mode 100755
similarity index 53%
rename from dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/AttributeOptions.php
rename to dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/EntityId.php
index 5000b9504b9855fab40faae2034090c9f3e631a5..6dd8cfc2dcf7ec2ba9d9c0b12a015d5fbaedeb49
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Fixture/CatalogProductConfigurable/AttributeOptions.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/EntityId.php
@@ -22,40 +22,63 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\ConfigurableProduct\Test\Fixture\CatalogProductConfigurable;
+namespace Magento\Review\Test\Fixture\ReviewInjectable;
 
 use Mtf\Fixture\FixtureFactory;
 use Mtf\Fixture\FixtureInterface;
+use Mtf\Fixture\InjectableFixture;
 
 /**
- * Class ConfigurableOptions
- *
- * Data keys:
- *  - preset (Attribute options preset name)
- *  - products (comma separated sku identifiers)
- *
+ * Class EntityId
+ * Source for entity id fixture
  */
-class AttributeOptions implements FixtureInterface
+class EntityId extends InjectableFixture
 {
     /**
-     * @var \Mtf\Fixture\FixtureFactory
+     * Configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Id of the created entity
+     *
+     * @var int
      */
-    protected $fixtureFactory;
+    protected $data = null;
 
     /**
+     * The created entity
+     *
+     * @var FixtureInterface
+     */
+    protected $entity = null;
+
+    /**
+     * @constructor
+     * @param FixtureFactory $fixtureFactory
      * @param array $params
-     * @param array $data
+     * @param array $data [optional]
      */
-    public function __construct(array $params, array $data = [])
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
     {
         $this->params = $params;
-        if (isset($data['preset'])) {
-            $this->data = $this->getPreset($data['preset']);
+
+        if (isset($data['dataSet'])) {
+            list($typeFixture, $dataSet) = explode('::', $data['dataSet']);
+            $fixture = $fixtureFactory->createByCode($typeFixture, ['dataSet' => $dataSet]);
+            if (!$fixture->hasData('id')) {
+                $fixture->persist();
+            }
+
+            $this->entity = $fixture;
+            $this->data = $fixture->getId();
         }
     }
 
     /**
-     * Persist attribute
+     * Persist data
      *
      * @return void
      */
@@ -65,10 +88,10 @@ class AttributeOptions implements FixtureInterface
     }
 
     /**
-     * Return prepared data set
+     * Return id of the created entity
      *
-     * @param $key [optional]
-     * @return mixed
+     * @param string|null $key [optional]
+     * @return int
      *
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
@@ -80,7 +103,7 @@ class AttributeOptions implements FixtureInterface
     /**
      * Return data set configuration settings
      *
-     * @return string
+     * @return array
      */
     public function getDataConfig()
     {
@@ -88,27 +111,12 @@ class AttributeOptions implements FixtureInterface
     }
 
     /**
-     * @param string $name
-     * @return array|null
+     * Get entity
+     *
+     * @return FixtureInterface|null
      */
-    protected function getPreset($name)
+    public function getEntity()
     {
-        $presets = [
-            'MAGETWO-23263' => [
-                'attribute_options' => [
-                    'attribute_label' => 'test%isolation%',
-                    'frontend_input' => 'Dropdown',
-                    'is_required' => 'No',
-                    'options' => [
-                        'option[value][option_0][0]' => 'option 0',
-                        'option[value][option_1][0]' => 'option 1',
-                    ]
-                ]
-            ],
-        ];
-        if (!isset($presets[$name])) {
-            return null;
-        }
-        return $presets[$name];
+        return $this->entity;
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/Ratings.php b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/Ratings.php
new file mode 100755
index 0000000000000000000000000000000000000000..cfd0a5f385ac393fd64434adbfcfa117af771534
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Fixture/ReviewInjectable/Ratings.php
@@ -0,0 +1,127 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Fixture\ReviewInjectable;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Magento\Review\Test\Fixture\Rating;
+
+/**
+ * Class Ratings
+ * Source for product ratings fixture
+ */
+class Ratings implements FixtureInterface
+{
+    /**
+     * Configuration settings of fixture
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Data of the created ratings
+     *
+     * @var array
+     */
+    protected $data = [];
+
+    /**
+     * List of the created ratings
+     *
+     * @var array
+     */
+    protected $ratings = [];
+
+    /**
+     * @constructor
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data [optional]
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+
+        foreach ($data as $rating) {
+            if (isset($rating['dataSet'])) {
+                /** @var Rating $fixtureRating */
+                $fixtureRating = $fixtureFactory->createByCode('rating', ['dataSet' => $rating['dataSet']]);
+                if (!$fixtureRating->hasData('id')) {
+                    $fixtureRating->persist();
+                }
+                $this->ratings[] = $fixtureRating;
+
+                $this->data[] = [
+                    'title' => $fixtureRating->getRatingCode(),
+                    'rating' => $rating['rating']
+                ];
+            }
+        }
+    }
+
+    /**
+     * Persist data
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return prepared data set
+     *
+     * @param string|null $key [optional]
+     * @return array
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Get ratings
+     *
+     * @return array
+     */
+    public function getRatings()
+    {
+        return $this->ratings;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
old mode 100644
new mode 100755
index 2672dc9b45a8517813fd79e1d33d7348cc4a1e22..9a1ab2ea29fd7b880ed9c582c3178fa19225ff5f
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/Curl.php
@@ -47,16 +47,22 @@ class Curl extends AbstractCurl implements RatingInterface
         'is_active' => [
             'Yes' => 1,
             'No' => 0,
-        ],
-        'stores' => [
-            'Main Website/Main Website Store/Default Store View' => 1
         ]
     ];
 
+    /**
+     * Mapping stores value
+     *
+     * @var array
+     */
+    protected $mappingStores = [
+        'Main Website/Main Website Store/Default Store View' => 1
+    ];
+
     /**
      * Post request for creating product Rating in backend
      *
-     * @param FixtureInterface|null $rating
+     * @param FixtureInterface|null $rating [optional]
      * @return array
      * @throws \Exception
      */
@@ -64,9 +70,10 @@ class Curl extends AbstractCurl implements RatingInterface
     {
         $url = $_ENV['app_backend_url'] . 'review/rating/save/';
         $curl = new BackendDecorator(new CurlTransport(), new Config());
-        $data = $this->replaceMappingData($rating->getData());
+        $data = $this->replaceMappingData($this->prepareData($rating->getData()));
 
         $data['stores'] = is_array($data['stores']) ? $data['stores'] : [$data['stores']];
+        $data += $this->getAdditionalData();
         $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
         $response = $curl->read();
         $curl->close();
@@ -76,13 +83,36 @@ class Curl extends AbstractCurl implements RatingInterface
             );
         }
 
-        return ['id' => $this->getProductRatingId()];
+        $ratingId = $this->getProductRatingId();
+        return [
+            'rating_id' => $ratingId,
+            'options' => $this->getRatingOptions($ratingId)
+        ];
+    }
+
+    /**
+     * Prepare POST data for creating rating request
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function prepareData(array $data)
+    {
+        if (isset($data['stores'])) {
+            foreach ($data['stores'] as $key => $store) {
+                if (isset($this->mappingStores[$store])) {
+                    $data['stores'][$key] = $this->mappingStores[$store];
+                }
+            }
+        }
+
+        return $data;
     }
 
     /**
      * Get product Rating id
      *
-     * @return int|null
+     * @return mixed
      */
     protected function getProductRatingId()
     {
@@ -93,4 +123,43 @@ class Curl extends AbstractCurl implements RatingInterface
 
         return empty($match[1]) ? null : $match[1];
     }
+
+    /**
+     * Get rating options
+     *
+     * @param int $ratingId
+     * @return array
+     */
+    protected function getRatingOptions($ratingId)
+    {
+        $url = 'review/rating/edit/id/' . $ratingId;
+        $regex = '/<input[^>]+name="option_title\[(\d+)\]"[^>]+>/';
+        $extractor = new Extractor($url, $regex, true);
+        $matches = $extractor->getData();
+
+        if (empty($matches[1])) {
+            return [];
+        }
+        array_unshift($matches[1], null);
+        return array_filter($matches[1]);
+    }
+
+    /**
+     * Return additional data for curl request
+     *
+     * @return array
+     */
+    protected function getAdditionalData()
+    {
+        return [
+            'rating_codes' => [1 => ''],
+            'option_title' => [
+                'add_1' => 1,
+                'add_2' => 2,
+                'add_3' => 3,
+                'add_4' => 4,
+                'add_5' => 5,
+            ],
+        ];
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/RatingInterface.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/Rating/RatingInterface.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/Curl.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/Curl.php
new file mode 100755
index 0000000000000000000000000000000000000000..7d5081e94cdb3fc7a4940d85059edd2657b81317
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/Curl.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Handler\ReviewInjectable;
+
+use Magento\Backend\Test\Handler\Extractor;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Magento\Review\Test\Fixture\Rating;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Handler\Curl as AbstractCurl;
+use Mtf\Util\Protocol\CurlInterface;
+use Mtf\Util\Protocol\CurlTransport\BackendDecorator;
+use Mtf\Util\Protocol\CurlTransport;
+use Mtf\System\Config;
+
+/**
+ * Class Curl
+ * Curl handler for creating product Review through backend.
+ */
+class Curl extends AbstractCurl implements ReviewInjectableInterface
+{
+    /**
+     * Mapping values for data.
+     *
+     * @var array
+     */
+    protected $mappingData = [
+        'status_id' => [
+            'Approved' => 1,
+            'Pending' => 2,
+            'Not Approved' => 3
+        ],
+        'stores' => [
+            'Main Website/Main Website Store/Default Store View' => 1
+        ]
+    ];
+
+    /**
+     * Post request for creating product Review in backend
+     *
+     * @param FixtureInterface|null $review [optional]
+     * @return array
+     * @throws \Exception
+     */
+    public function persist(FixtureInterface $review = null)
+    {
+        /** @var ReviewInjectable $review */
+        $url = $_ENV['app_backend_url'] . 'review/product/post/';
+        $curl = new BackendDecorator(new CurlTransport(), new Config());
+        $data = $this->replaceMappingData($this->getPreparedData($review));
+
+        $curl->write(CurlInterface::POST, $url, '1.0', [], $data);
+        $response = $curl->read();
+        $curl->close();
+        if (!strpos($response, 'data-ui-id="messages-message-success"')) {
+            throw new \Exception(
+                'Product Review entity creating by curl handler was not successful! Response:' . $response
+            );
+        }
+
+        return ['review_id' => $this->getReviewId()];
+    }
+
+    /**
+     * Prepare and return data of review
+     *
+     * @param FixtureInterface $review
+     * @return array
+     */
+    protected function getPreparedData(FixtureInterface $review)
+    {
+        $data = $review->getData();
+
+        /* Prepare ratings */
+        $sourceRatings = $review->getDataFieldConfig('ratings')['source'];
+        $ratings = [];
+        foreach ($data['ratings'] as $rating) {
+            $ratings[$rating['title']] = $rating['rating'];
+        }
+        $data['ratings'] = [];
+        foreach ($sourceRatings->getRatings() as $ratingFixture) {
+            /** @var Rating $ratingFixture */
+            $ratingCode = $ratingFixture->getRatingCode();
+            if (isset($ratings[$ratingCode])) {
+                $ratingOptions = $ratingFixture->getOptions();
+                $vote = $ratings[$ratingCode];
+                $data['ratings'][$ratingFixture->getRatingId()] = $ratingOptions[$vote];
+            }
+        }
+
+        /* prepare product id */
+        $data['product_id'] = $data['entity_id'];
+        unset($data['entity_id']);
+
+        return $data;
+    }
+
+    /**
+     * Get product Rating id
+     *
+     * @return int|null
+     */
+    protected function getReviewId()
+    {
+        $url = 'review/product/index/sort/review_id/dir/desc/';
+        $regex = '/class="[^"]+col-id[^"]+"[^>]*>\s*([0-9]+)\s*</';
+        $extractor = new Extractor($url, $regex);
+        $match = $extractor->getData();
+
+        return empty($match[1]) ? null : $match[1];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/ReviewInjectableInterface.php b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/ReviewInjectableInterface.php
new file mode 100755
index 0000000000000000000000000000000000000000..0045cdc0a3383c5597158299b3568f27f8e4015e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Handler/ReviewInjectable/ReviewInjectableInterface.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Handler\ReviewInjectable;
+
+use Mtf\Handler\HandlerInterface;
+
+/**
+ * Interface ReviewInjectableInterface
+ */
+interface ReviewInjectableInterface extends HandlerInterface
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingEdit.php b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingEdit.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingEdit.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingEdit.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingIndex.php b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingIndex.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingIndex.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingIndex.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingNew.php b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingNew.php
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingNew.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/RatingNew.xml
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.php b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.php
new file mode 100755
index 0000000000000000000000000000000000000000..69c149371a40d171b58eb967f7f6c742741759a9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class ReviewEdit
+ */
+class ReviewEdit extends BackendPage
+{
+    const MCA = 'review/product/edit';
+
+    protected $_blocks = [
+        'pageActions' => [
+            'name' => 'pageActions',
+            'class' => 'Magento\Review\Test\Block\Adminhtml\FormPageActions',
+            'locator' => '.page-main-actions',
+            'strategy' => 'css selector',
+        ],
+        'reviewForm' => [
+            'name' => 'reviewForm',
+            'class' => 'Magento\Review\Test\Block\Adminhtml\ReviewForm',
+            'locator' => '#edit_form',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Review\Test\Block\Adminhtml\FormPageActions
+     */
+    public function getPageActions()
+    {
+        return $this->getBlockInstance('pageActions');
+    }
+
+    /**
+     * @return \Magento\Review\Test\Block\Adminhtml\ReviewForm
+     */
+    public function getReviewForm()
+    {
+        return $this->getBlockInstance('reviewForm');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.xml
new file mode 100755
index 0000000000000000000000000000000000000000..b006f73960ec173cf746e44d6cffba1304759a76
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewEdit.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="review/product/edit" >
+    <block>
+        <name>pageActions</name>
+        <class>Magento\Review\Test\Block\Adminhtml\FormPageActions</class>
+        <locator>.page-main-actions</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>reviewForm</name>
+        <class>Magento\Review\Test\Block\Adminhtml\ReviewForm</class>
+        <locator>#edit_form</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.php b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c551b35a5e704ddeb921ee4e2a66efdbdb77a58
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Page\Adminhtml;
+
+use Mtf\Page\BackendPage;
+
+/**
+ * Class ReviewIndex
+ *
+ * @package Magento\Review\Test\Page\Adminhtml
+ */
+class ReviewIndex extends BackendPage
+{
+    const MCA = 'review/product/index';
+
+    protected $_blocks = [
+        'messagesBlock' => [
+            'name' => 'messagesBlock',
+            'class' => 'Magento\Core\Test\Block\Messages',
+            'locator' => '#messages',
+            'strategy' => 'css selector',
+        ],
+        'reviewGrid' => [
+            'name' => 'reviewGrid',
+            'class' => 'Magento\Review\Test\Block\Adminhtml\Grid',
+            'locator' => '#reviwGrid',
+            'strategy' => 'css selector',
+        ],
+    ];
+
+    /**
+     * @return \Magento\Core\Test\Block\Messages
+     */
+    public function getMessagesBlock()
+    {
+        return $this->getBlockInstance('messagesBlock');
+    }
+
+    /**
+     * @return \Magento\Review\Test\Block\Adminhtml\Grid
+     */
+    public function getReviewGrid()
+    {
+        return $this->getBlockInstance('reviewGrid');
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.xml b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.xml
new file mode 100755
index 0000000000000000000000000000000000000000..42bb5169639c4587e62b92c172255c07fc6a0912
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Page/Adminhtml/ReviewIndex.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Academic Free License (AFL 3.0)
+ * that is bundled with this package in the file LICENSE_AFL.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/afl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
+ */
+-->
+<page mca="review/product/index" >
+    <block>
+        <name>messagesBlock</name>
+        <class>Magento\Core\Test\Block\Messages</class>
+        <locator>#messages</locator>
+        <strategy>css selector</strategy>
+    </block>
+    <block>
+        <name>reviewGrid</name>
+        <class>Magento\Review\Test\Block\Adminhtml\Grid</class>
+        <locator>#reviwGrid</locator>
+        <strategy>css selector</strategy>
+    </block>
+</page>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Rating.php b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Rating.php
old mode 100644
new mode 100755
index 5b249be324f6931e084478ceef091f0435555134..d0823bed90c334fe08d03375ebfcfdb001666fc8
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Rating.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Rating.php
@@ -46,5 +46,11 @@ class Rating extends AbstractRepository
             'stores' => ['Main Website/Main Website Store/Default Store View'],
             'is_active' => 'Yes',
         ];
+
+        $this->_data['visibleOnDefaultWebsite'] = [
+            'rating_code' => 'productRating_%isolation%',
+            'stores' => ['Main Website/Main Website Store/Default Store View'],
+            'is_active' => 'Yes'
+        ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Review.php b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Review.php
old mode 100644
new mode 100755
index ef07215fe973f890ae824de95797f8b19cbbc34b..1aaffd57bda575e66280b81d624f0564851d6d71
--- a/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Review.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/Review.php
@@ -28,7 +28,6 @@ use Mtf\Repository\AbstractRepository;
 
 /**
  * Review Repository
- *
  */
 class Review extends AbstractRepository
 {
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/Repository/ReviewInjectable.php b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/ReviewInjectable.php
new file mode 100755
index 0000000000000000000000000000000000000000..e97d0ce7e6de8fc3579f8604796f5b8548167908
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/Repository/ReviewInjectable.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\Repository;
+
+use Mtf\Repository\AbstractRepository;
+
+/**
+ * Class ReviewInjectable
+ * Data for creation product Review
+ */
+class ReviewInjectable extends AbstractRepository
+{
+    /**
+     * @constructor
+     * @param array $defaultConfig
+     * @param array $defaultData
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function __construct(array $defaultConfig = [], array $defaultData = [])
+    {
+        $this->_data['review_for_simple_product_with_rating'] = [
+            'status_id' => 'Approved',
+            'select_stores' => ['Main Website/Main Website Store/Default Store View'],
+            'nickname' => 'nickname_%isolation%',
+            'title' => 'title_%isolation%',
+            'detail' => 'review_detail_%isolation%',
+            'ratings' => [
+                1 => [
+                    'dataSet' => 'visibleOnDefaultWebsite',
+                    'rating' => mt_rand(1, 5)
+                ]
+            ],
+            'entity_id' => ['dataSet' => 'catalogProductSimple::default']
+        ];
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..fd06461a5a405e12519f3f36a76dfe00218fb1d5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\TestCase;
+
+use Magento\Catalog\Test\Fixture\CatalogProductSimple;
+use Magento\Catalog\Test\Page\Product\CatalogProductView;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Magento\Review\Test\Page\Adminhtml\RatingEdit;
+use Magento\Review\Test\Page\Adminhtml\RatingIndex;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for Create Frontend Product Review
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create simple product
+ * 2. Create custom rating type
+ *
+ * Steps:
+ * 1. Open frontend
+ * 2. Go to product page
+ * 3. Click "Be the first to review this product"
+ * 4. Fill data according to dataset
+ * 5. click "Submit review"
+ * 6. Perform all assertions
+ *
+ * @group Reviews_and_Ratings_(MX)
+ * @ZephyrId MAGETWO-25519
+ */
+class CreateFrontendProductReviewEntityTest extends Injectable
+{
+    /**
+     * Frontend product view page
+     *
+     * @var CatalogProductView
+     */
+    protected $catalogProductView;
+
+    /**
+     * Backend rating grid page
+     *
+     * @var RatingIndex
+     */
+    protected $ratingIndex;
+
+    /**
+     * Backend rating edit page
+     *
+     * @var RatingEdit
+     */
+    protected $ratingEdit;
+
+    /**
+     * Fixture review
+     *
+     * @var ReviewInjectable
+     */
+    protected $review;
+
+    /**
+     * Prepare data
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $product = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => 'default']);
+        $product->persist();
+
+        return ['product' => $product];
+    }
+
+    /**
+     * Injection data
+     *
+     * @param CatalogProductView $catalogProductView
+     * @param RatingIndex $ratingIndex
+     * @param RatingEdit $ratingEdit
+     * @return void
+     */
+    public function __inject(
+        CatalogProductView $catalogProductView,
+        RatingIndex $ratingIndex,
+        RatingEdit $ratingEdit
+    ) {
+        $this->catalogProductView = $catalogProductView;
+        $this->ratingIndex = $ratingIndex;
+        $this->ratingEdit = $ratingEdit;
+    }
+
+    /**
+     * Run create frontend product rating test
+     *
+     * @param CatalogProductSimple $product
+     * @param ReviewInjectable $review
+     * @return void
+     */
+    public function test(
+        CatalogProductSimple $product,
+        ReviewInjectable $review
+    ) {
+        // Prepare for tear down
+        $this->review = $review;
+
+        // Steps
+        $this->catalogProductView->init($product);
+        $this->catalogProductView->open();
+        $this->catalogProductView->getReviewSummaryBlock()->getAddReviewLink()->click();
+
+        $reviewForm = $this->catalogProductView->getReviewFormBlock();
+        $reviewForm->fill($review);
+        $reviewForm->submit();
+    }
+
+    /**
+     * Clear data after test
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->ratingIndex->open();
+        $ratingGrid = $this->ratingIndex->getRatingGrid();
+        $pageActions = $this->ratingEdit->getPageActions();
+        foreach ($this->review->getRatings() as $rating) {
+            $filter = ['rating_code' => $rating['title']];
+            $ratingGrid->searchAndOpen($filter);
+            $pageActions->delete();
+        }
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest/test.csv
new file mode 100755
index 0000000000000000000000000000000000000000..c292f94db4dd652ddb7e86fee33dc7e991d26674
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateFrontendProductReviewEntityTest/test.csv
@@ -0,0 +1,2 @@
+"review/data/nickname";"review/data/title";"review/data/detail";"review/data/ratings/1/dataSet";"review/data/ratings/1/rating";"constraint"
+"name_%isolation%";"title_%isolation%";"review_%isolation%";"visibleOnDefaultWebsite";"4";"assertReviewCreationSuccessMessage, assertProductReviewInGrid, assertProductRatingOnReviewPage, assertProductRatingInProductPage"
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php
old mode 100644
new mode 100755
index 5d6f3dda381ec87c8609f384f32bcc3208086173..413bf728aba60efb9116addfc60fd467312e194a
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest.php
@@ -27,8 +27,8 @@ namespace Magento\Review\Test\TestCase;
 use Magento\Review\Test\Page\Adminhtml\RatingIndex;
 use Magento\Review\Test\Page\Adminhtml\RatingNew;
 use Magento\Review\Test\Page\Adminhtml\RatingEdit;
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Review\Test\Fixture\Rating;
+use Mtf\Fixture\FixtureFactory;
 use Mtf\TestCase\Injectable;
 
 /**
@@ -72,6 +72,20 @@ class CreateProductRatingEntityTest extends Injectable
      */
     protected $ratingEdit;
 
+    /**
+     * Prepare data
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $product = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => 'default']);
+        $product->persist();
+
+        return ['product' => $product];
+    }
+
     /**
      * Injection data
      *
@@ -93,25 +107,19 @@ class CreateProductRatingEntityTest extends Injectable
     /**
      * Run create backend Product Rating test
      *
-     * @param CatalogProductSimple $product
      * @param Rating $productRating
      * @return void
      */
-    public function testCreateProductRatingEntityTest(
-        CatalogProductSimple $product,
-        Rating $productRating
-    ) {
-        // Preconditions
-        $product->persist();
+    public function testCreateProductRatingEntityTest(Rating $productRating)
+    {
+        // Prepare data for tear down
+        $this->productRating = $productRating;
 
         // Steps
         $this->ratingIndex->open();
         $this->ratingIndex->getGridPageActions()->addNew();
         $this->ratingNew->getRatingForm()->fill($productRating);
         $this->ratingNew->getPageActions()->save();
-
-        // Prepare data for tear down
-        $this->productRating = $productRating;
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest/testCreateProductRatingEntityTest.csv b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/CreateProductRatingEntityTest/testCreateProductRatingEntityTest.csv
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php
old mode 100644
new mode 100755
index a9d58fc44b1775c61641bab82f0befc098d3cb91..5f9fc57b86068dc05d796ad1f32360cef39f8a7f
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest.php
@@ -23,10 +23,10 @@
  */
 namespace Magento\Review\Test\TestCase;
 
-use Magento\Catalog\Test\Fixture\CatalogProductSimple;
 use Magento\Review\Test\Fixture\Rating;
 use Magento\Review\Test\Page\Adminhtml\RatingEdit;
 use Magento\Review\Test\Page\Adminhtml\RatingIndex;
+use Mtf\Fixture\FixtureFactory;
 use Mtf\TestCase\Injectable;
 
 /**
@@ -64,12 +64,14 @@ class DeleteProductRatingEntityTest extends Injectable
     /**
      * Prepare data
      *
-     * @param CatalogProductSimple $product
+     * @param FixtureFactory $fixtureFactory
      * @return array
      */
-    public function __prepare(CatalogProductSimple $product)
+    public function __prepare(FixtureFactory $fixtureFactory)
     {
+        $product = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => 'default']);
         $product->persist();
+
         return ['product' => $product];
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest/testDeleteProductRatingEntity.csv b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/DeleteProductRatingEntityTest/testDeleteProductRatingEntity.csv
old mode 100644
new mode 100755
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
old mode 100644
new mode 100755
index 1e6d249e032b30a21ebb5de61697c2e3e895eeee..732a83d475dab0fa04931515c551a8e1a76e59c9
--- a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/ReviewTest.php
@@ -53,12 +53,13 @@ class ReviewTest extends Functional
         //Pages & Blocks
         $homePage = Factory::getPageFactory()->getCmsIndexIndex();
         $productPage = Factory::getPageFactory()->getCatalogProductView();
-        $backendReviewPage = Factory::getPageFactory()->getReviewProduct();
+        $backendReviewIndex = Factory::getPageFactory()->getReviewProductIndex();
+        $backendReviewEdit = Factory::getPageFactory()->getReviewProductEdit();
         $reviewsSummaryBlock = $productPage->getReviewSummaryBlock();
         $reviewsBlock = $productPage->getCustomerReviewBlock();
         $reviewForm = $productPage->getReviewFormBlock();
-        $reviewGrid = $backendReviewPage->getGridBlock();
-        $reviewBackendForm = $backendReviewPage->getEditForm();
+        $reviewGrid = $backendReviewIndex->getReviewGrid();
+        $reviewBackendForm = $backendReviewEdit->getReviewForm();
 
         //Steps & verifying
         $homePage->open();
@@ -80,7 +81,7 @@ class ReviewTest extends Functional
         $this->verifyNoReviewOnPage($productPage->getReviewSummaryBlock());
 
         Factory::getApp()->magentoBackendLoginUser();
-        $backendReviewPage->open();
+        $backendReviewIndex->open();
         $reviewGrid->searchAndOpen(array('title' => $reviewFixture->getTitle()));
         $this->assertEquals('Guest', $reviewBackendForm->getPostedBy(), 'Review is not posted by Guest');
         $this->assertEquals('Pending', $reviewBackendForm->getStatus(), 'Review is not in Pending status');
@@ -89,10 +90,11 @@ class ReviewTest extends Functional
             'Review data is not corresponds to submitted one'
         );
 
-        $reviewBackendForm->approveReview();
+        $reviewBackendForm->setApproveReview();
+        $backendReviewEdit->getPageActions()->save();
         $this->assertContains(
             'You saved the review.',
-            $backendReviewPage->getMessagesBlock()->getSuccessMessages(),
+            $backendReviewIndex->getMessagesBlock()->getSuccessMessages(),
             'Review is not saved'
         );
 
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..e44a7a9b271d87922cbcc59dad68171b0e7f5c68
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest.php
@@ -0,0 +1,165 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Review\Test\TestCase;
+
+use Magento\Review\Test\Page\Adminhtml\ReviewIndex;
+use Magento\Review\Test\Page\Adminhtml\ReviewEdit;
+use Magento\Review\Test\Page\Adminhtml\RatingIndex;
+use Magento\Review\Test\Page\Adminhtml\RatingEdit;
+use Magento\Review\Test\Fixture\ReviewInjectable;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for Update Frontend Product Review
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create simple product
+ * 2. Create custom rating type
+ * 3. Create review with rating
+ *
+ * Steps:
+ * 1. Open backend
+ * 2. Go to Marketing> Reviews
+ * 3. Open created review
+ * 4. Fill data according to dataset
+ * 5. Click "Submit review"
+ * 6. Perform all assertions
+ *
+ * @group Reviews_and_Ratings_(MX)
+ * @ZephyrId MAGETWO-25604
+ */
+class UpdateProductReviewEntityTest extends Injectable
+{
+    /**
+     * Backend review grid page
+     *
+     * @var ReviewIndex
+     */
+    protected $reviewIndex;
+
+    /**
+     * Backend review edit page
+     *
+     * @var ReviewEdit
+     */
+    protected $reviewEdit;
+
+    /**
+     * Backend rating grid page
+     *
+     * @var RatingIndex
+     */
+    protected $ratingIndex;
+
+    /**
+     * Backend rating edit page
+     *
+     * @var RatingEdit
+     */
+    protected $ratingEdit;
+
+    /**
+     * Fixture review
+     *
+     * @var ReviewInjectable
+     */
+    protected $review;
+
+    /**
+     * Prepare data
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $product = $fixtureFactory->createByCode('catalogProductSimple', ['dataSet' => 'default']);
+        $product->persist();
+
+        return ['product' => $product];
+    }
+
+    /**
+     * Injection data
+     *
+     * @param ReviewIndex $reviewIndex
+     * @param ReviewEdit $reviewEdit
+     * @param RatingIndex $ratingIndex
+     * @param RatingEdit $ratingEdit
+     * @return void
+     */
+    public function __inject(
+        ReviewIndex $reviewIndex,
+        ReviewEdit $reviewEdit,
+        RatingIndex $ratingIndex,
+        RatingEdit $ratingEdit
+    ) {
+        $this->reviewIndex = $reviewIndex;
+        $this->reviewEdit = $reviewEdit;
+        $this->ratingIndex = $ratingIndex;
+        $this->ratingEdit = $ratingEdit;
+    }
+
+    /**
+     * Run create frontend product rating test
+     *
+     * @param ReviewInjectable $reviewInitial
+     * @param ReviewInjectable $review
+     * @return void
+     */
+    public function test(ReviewInjectable $reviewInitial, ReviewInjectable $review)
+    {
+        // Precondition
+        $reviewInitial->persist();
+
+        // Prepare for tear down
+        $this->review = $reviewInitial;
+
+        // Steps
+        $this->reviewIndex->open();
+        $this->reviewIndex->getReviewGrid()->searchAndOpen(['review_id' => $reviewInitial->getReviewId()]);
+        $this->reviewEdit->getReviewForm()->fill($review);
+        $this->reviewEdit->getPageActions()->save();
+    }
+
+    /**
+     * Clear data after test
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->ratingIndex->open();
+        $ratingGrid = $this->ratingIndex->getRatingGrid();
+        $pageActions = $this->ratingEdit->getPageActions();
+        foreach ($this->review->getRatings() as $rating) {
+            $ratingGrid->searchAndOpen(['rating_code' => $rating['title']]);
+            $pageActions->delete();
+        }
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest/test.csv
new file mode 100755
index 0000000000000000000000000000000000000000..61c7b4c886e31754c23459361566f4652fe98600
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/TestCase/UpdateProductReviewEntityTest/test.csv
@@ -0,0 +1,2 @@
+"reviewInitial/dataSet";"review/data/nickname";"review/data/title";"review/data/detail";"constraint"
+"review_for_simple_product_with_rating";"name_upd_%isolation%";"title_upd_%isolation%";"review_upd_%isolation%";"assertReviewSuccessSaveMessage, assertProductReviewInGrid, assertProductRatingOnReviewPage"
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/Review/Test/etc/curl/di.xml
old mode 100644
new mode 100755
index fa49f6b3789386ee515c6fd3a921cb216d39ad5d..dac4ced8daacb04e4751ac2ba3c626384715c0fd
--- a/dev/tests/functional/tests/app/Magento/Review/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/etc/curl/di.xml
@@ -25,4 +25,5 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
     <preference for="Magento\Review\Test\Handler\Rating\RatingInterface" type="\Magento\Review\Test\Handler\Rating\Curl"/>
+    <preference for="Magento\Review\Test\Handler\ReviewInjectable\ReviewInjectableInterface" type="\Magento\Review\Test\Handler\ReviewInjectable\Curl"/>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/constraint.xml
old mode 100644
new mode 100755
index d6f63c99b49b5fea30490965bea1ef2e1c3cd201..cb017639675d82e2f5a6cad8065e49600ed6c59a
--- a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/constraint.xml
@@ -42,4 +42,19 @@
     <assertProductRatingNotInProductPage module="Magento_Review">
         <severeness>middle</severeness>
     </assertProductRatingNotInProductPage>
+    <assertReviewSuccessSaveMessage module="Magento_Review">
+        <severeness>high</severeness>
+    </assertReviewSuccessSaveMessage>
+    <assertReviewCreationSuccessMessage module="Magento_Review">
+        <severeness>high</severeness>
+    </assertReviewCreationSuccessMessage>
+    <assertProductReviewInGrid module="Magento_Review">
+        <severeness>low</severeness>
+    </assertProductReviewInGrid>
+    <assertProductRatingOnReviewPage module="Magento_Review">
+        <severeness>middle</severeness>
+    </assertProductRatingOnReviewPage>
+    <assertProductRatingInProductPage module="Magento_Review">
+        <severeness>middle</severeness>
+    </assertProductRatingInProductPage>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/fixture.xml
old mode 100644
new mode 100755
index 0166d4b58be186495d081d6f05caeffcb2e649a8..c7eb798f99edb9d5ea5774dca5862bf9af0b17e3
--- a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/fixture.xml
@@ -24,20 +24,14 @@
  */
 -->
 <fixture>
-    <review module="Magento_Review">
-        <type>flat</type>
-        <entity_type>review</entity_type>
+    <reviewInjectable module="Magento_Review">
+        <type>composite</type>
+        <entities>
+            <review>review</review>
+            <review_detail>review_detail</review_detail>
+        </entities>
         <collection>Magento\Review\Model\Resource\Review\Collection</collection>
-        <identifier />
-        <fields>
-            <id>
-                <attribute_code>id</attribute_code>
-                <backend_type>virtual</backend_type>
-            </id>
-        </fields>
-        <data_set />
-        <data_config />
-    </review>
+    </reviewInjectable>
     <rating module="Magento_Review">
         <type>flat</type>
         <entity_type>rating</entity_type>
diff --git a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/page.xml b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/page.xml
old mode 100644
new mode 100755
index 073472b1b1eb65b04d3d03eb841a2aa93a80e695..627453cea112d66d80f5f6698bd3b26566854720
--- a/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/page.xml
+++ b/dev/tests/functional/tests/app/Magento/Review/Test/etc/global/page.xml
@@ -39,4 +39,14 @@
         <area>adminhtml</area>
         <class>Magento\Review\Test\Page\Adminhtml\RatingEdit</class>
     </ratingEdit>
+    <reviewIndex>
+        <mca>review/product/index</mca>
+        <area>adminhtml</area>
+        <class>Magento\Review\Test\Page\Adminhtml\ReviewIndex</class>
+    </reviewIndex>
+    <reviewEdit>
+        <mca>review/product/edit</mca>
+        <area>adminhtml</area>
+        <class>Magento\Review\Test\Page\Adminhtml\ReviewEdit</class>
+    </reviewEdit>
 </page>
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/GenerateSitemapEntityTest/testGenerateSitemap.csv b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/GenerateSitemapEntityTest/testGenerateSitemap.csv
index 083f1b38cb9272be5a07690db082e14b48e8ac96..8a3137d9e6e7996d3ee183416dbf0b45604076be 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/GenerateSitemapEntityTest/testGenerateSitemap.csv
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/GenerateSitemapEntityTest/testGenerateSitemap.csv
@@ -1,2 +1,2 @@
 "catalog/dataSet";"product/dataSet";"cmsPage/dataSet";"sitemap/data/sitemap_filename";"sitemap/data/sitemap_path";"constraint"
-"default_category";"default";"default";"sitemap.xml";"/";"assertSitemapSuccessSaveAndGenerateMessages, assertSitemapContent, assertSitemapInGrid"
\ No newline at end of file
+"default_subcategory";"default";"default";"sitemap.xml";"/";"assertSitemapSuccessSaveAndGenerateMessages, assertSitemapContent, assertSitemapInGrid"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/UpdateSitemapEntityTest/testUpdateSitemap.csv b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/UpdateSitemapEntityTest/testUpdateSitemap.csv
index 2033e2a90f375320e691d4b9d45db0554b3f2929..e7967ddf2af6af789beb319b00920fa15dbb2518 100644
--- a/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/UpdateSitemapEntityTest/testUpdateSitemap.csv
+++ b/dev/tests/functional/tests/app/Magento/Sitemap/Test/TestCase/UpdateSitemapEntityTest/testUpdateSitemap.csv
@@ -1,2 +1,2 @@
 "catalog/dataSet";"product/dataSet";"cmsPage/dataSet";"sitemap/dataSet";"constraint"
-"default_category";"default";"default";"default";"assertSitemapSuccessGenerateMessage, assertSitemapContent"
+"default_subcategory";"default";"default";"default";"assertSitemapSuccessGenerateMessage, assertSitemapContent"
diff --git a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php
index ce223db86e2f00b6bdd9c746004d9aa8c9d77161..de121dfc68d016ce8e487c765fe349af804bad60 100644
--- a/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php
+++ b/dev/tests/functional/tests/app/Magento/Theme/Test/Block/Html/Topmenu.php
@@ -22,6 +22,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
+
 namespace Magento\Theme\Test\Block\Html;
 
 use Mtf\Block\Block;
@@ -68,11 +69,44 @@ class Topmenu extends Block
      * @return void
      */
     public function selectCategoryByName($categoryName)
+    {
+        $rootElement = $this->_rootElement;
+        $category = $this->waitLoadTopMenu($categoryName);
+        if ($category[1]) {
+            $rootElement->waitUntil(
+                function () use ($category) {
+                    return $category[0]->isVisible() ? true : null;
+                }
+            );
+        }
+        sleep(1); // TODO: sleep should be removed after fix with category sliding
+        $category[0]->click();
+    }
+
+    /**
+     * Check is visible category in top menu by name
+     *
+     * @param string $categoryName
+     * @return bool
+     */
+    public function isCategoryVisible($categoryName)
+    {
+        return $this->waitLoadTopMenu($categoryName)[0]->isVisible();
+    }
+
+    /**
+     * Wait for load top menu
+     *
+     * @param string $categoryName
+     * @return array
+     */
+    protected function waitLoadTopMenu($categoryName)
     {
         $rootElement = $this->_rootElement;
         $moreCategoriesLink = $rootElement->find($this->moreParentCategories);
         $submenu = $moreCategoriesLink->find($this->submenu);
         $category = $rootElement->find(sprintf($this->category, $categoryName), Locator::SELECTOR_XPATH);
+        $notFindCategory = !$category->isVisible() && $moreCategoriesLink->isVisible();
         if (!$category->isVisible() && $moreCategoriesLink->isVisible()) {
             $rootElement->waitUntil(
                 function () use ($rootElement, $moreCategoriesLink, $submenu) {
@@ -81,14 +115,8 @@ class Topmenu extends Block
                     return $submenu->isVisible() ? true : null;
                 }
             );
-            $rootElement->waitUntil(
-                function () use ($category) {
-                    return $category->isVisible() ? true : null;
-                }
-            );
         }
-        sleep(1); // TODO: sleep should be removed after fix with category sliding
-        $category->click();
+        return [$category, $notFindCategory];
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php
index f4489b10a08421dd755f929ccbf26c3aada01145..bbd0b6da9bd1cddb46959256625c3ce92321ea0c 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.php
@@ -24,6 +24,8 @@
 
 namespace Magento\UrlRewrite\Test\Block\Adminhtml\Catalog\Edit;
 
+use Mtf\Client\Element;
+use Mtf\Fixture\FixtureInterface;
 use Magento\Backend\Test\Block\Widget\Form as FormWidget;
 
 /**
@@ -32,5 +34,28 @@ use Magento\Backend\Test\Block\Widget\Form as FormWidget;
  */
 class Form extends FormWidget
 {
-    //
+    /**
+     * Fill the root form
+     *
+     * @param FixtureInterface $fixture
+     * @param Element|null $element
+     * @return $this
+     */
+    public function fill(FixtureInterface $fixture, Element $element = null)
+    {
+        $data = $fixture->getData();
+        $getData = $this->getData();
+        if (!$getData['target_path']) {
+            $entity = $fixture->getDataFieldConfig('id_path')['source']->getEntity();
+            $data['target_path'] = $entity->hasData('identifier')
+                ? $entity->getIdentifier()
+                : $entity->getUrlKey() . '.html';
+        }
+        // TODO: delete line after removing old fixture
+        $fields = isset($data['fields']) ? $data['fields'] : $data;
+        $mapping = $this->dataMapping($fields);
+        $this->_fill($mapping, $element);
+
+        return $this;
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml
index be3ef675c59066ed518b9f1dd495f5ce00b4d16c..4e4369a77d2820a4d5ce16c9c7bc9c27c477405d 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Block/Adminhtml/Catalog/Edit/Form.xml
@@ -41,6 +41,10 @@
             <selector>[name='request_path']</selector>
             <input>text</input>
         </request_path>
+        <target_path>
+            <selector>[name='target_path']</selector>
+            <input>text</input>
+        </target_path>
         <description>
             <selector>[name='description']</selector>
             <input>text</input>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
index b82b58bd5ccb7afc97c23f2e68ece9202f1b3fde..c5ba06e20a144eabe14a5dbec799d945bd7d0f08 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCategoryRedirect.php
@@ -58,7 +58,7 @@ class AssertUrlRewriteCategoryRedirect extends AbstractConstraint
         $browser->open($_ENV['app_frontend_url'] . $urlRewrite->getRequestPath());
         $url = $urlRewrite->getOptions() == 'No'
             ? $urlRewrite->getRequestPath()
-            : strtolower($category->getName()) . '.html';
+            : $category->getUrlKey() . '.html';
 
         \PHPUnit_Framework_Assert::assertEquals(
             $browser->getUrl(),
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomRedirect.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomRedirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a1dd11246de1546ee0867a515d16b2a102ee56d
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Constraint/AssertUrlRewriteCustomRedirect.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\UrlRewrite\Test\Constraint;
+
+use Mtf\Client\Browser;
+use Magento\Cms\Test\Page\CmsIndex;
+use Mtf\Constraint\AbstractConstraint;
+use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+
+/**
+ * Class AssertUrlRewriteCustomRedirect
+ * Assert check URL rewrite custom redirect
+ */
+class AssertUrlRewriteCustomRedirect extends AbstractConstraint
+{
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Assert check URL rewrite custom redirect
+     *
+     * @param UrlRewrite $urlRewrite
+     * @param Browser $browser
+     * @param CmsIndex $cmsIndex
+     * @return void
+     */
+    public function processAssert(UrlRewrite $urlRewrite, Browser $browser, CmsIndex $cmsIndex)
+    {
+        $browser->open($_ENV['app_frontend_url'] . $urlRewrite->getRequestPath());
+        $entity = $urlRewrite->getDataFieldConfig('id_path')['source']->getEntity();
+        $title = $entity->hasData('name') ? $entity->getName() : $entity->getTitle();
+        $pageTitle = $cmsIndex->getTitleBlock()->getTitle();
+        \PHPUnit_Framework_Assert::assertEquals(
+            $pageTitle,
+            $title,
+            'URL rewrite product redirect false.'
+            . "\nExpected: " . $title
+            . "\nActual: " . $pageTitle
+        );
+    }
+
+    /**
+     * Returns a string representation of the object
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Custom URL rewrite redirect was success.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
index 8b115150414939e4d6313eda1964fa6186b092a3..e8dd121aec0b7c7582ec973896aa6765cbaf21b0 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.php
@@ -80,6 +80,14 @@ class UrlRewrite extends InjectableFixture
         'input' => 'text',
     ];
 
+    protected $target_path = [
+        'attribute_code' => 'target_path',
+        'backend_type' => 'varchar',
+        'is_required' => '1',
+        'default_value' => 'target_path%isolation%',
+        'input' => 'text',
+    ];
+
     protected $description = [
         'attribute_code' => 'description',
         'backend_type' => 'varchar',
@@ -112,6 +120,11 @@ class UrlRewrite extends InjectableFixture
         return $this->getData('request_path');
     }
 
+    public function getTargetPath()
+    {
+        return $this->getData('target_path');
+    }
+
     public function getDescription()
     {
         return $this->getData('description');
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
index 20e71d8cb3dc84901948caea7e0895f141d1b76d..f5be3f2336ef0cf1cb6ad405a708a262ae370034 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite.xml
@@ -56,6 +56,13 @@
             <default_value>request_path%isolation%</default_value>
             <input>text</input>
         </request_path>
+        <target_path>
+            <attribute_code>target_path</attribute_code>
+            <backend_type>varchar</backend_type>
+            <is_required>1</is_required>
+            <default_value>target_path%isolation%</default_value>
+            <input>text</input>
+        </target_path>
         <description>
             <attribute_code>description</attribute_code>
             <backend_type>varchar</backend_type>
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php
index fee524bd331495746f78ca149b83e5c3787a16e5..20851760e2b312adb434a8ae2812feacefa035b5 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/Fixture/UrlRewrite/IdPath.php
@@ -47,6 +47,13 @@ class IdPath implements FixtureInterface
      */
     protected $entity;
 
+    /**
+     * Data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
     /**
      * @param FixtureFactory $fixtureFactory
      * @param array $params
@@ -65,7 +72,8 @@ class IdPath implements FixtureInterface
             /** @var FixtureInterface $fixture */
             $this->entity = $fixtureFactory->createByCode($explodeValue[0], ['dataSet' => $explodeValue[1]]);
             $this->entity->persist();
-            $this->data = preg_replace('`(%.*?%)`', $this->entity->getId(), $data['entity']);
+            $id = $this->entity->hasData('id') ? $this->entity->getId() : $this->entity->getPageId();
+            $this->data = preg_replace('`(%.*?%)`', $id, $data['entity']);
         } else {
             $this->data = strval($data['entity']);
         }
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9816b32dac117daf359b3bffda480d04e36c6186
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\UrlRewrite\Test\TestCase;
+
+use Mtf\TestCase\Injectable;
+use Magento\UrlRewrite\Test\Fixture\UrlRewrite;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteEdit;
+use Magento\UrlRewrite\Test\Page\Adminhtml\UrlrewriteIndex;
+
+/**
+ * Test Creation for CreateCustomUrlRewriteEntity
+ *
+ * Test Flow:
+ *
+ * Preconditions:
+ * 1. Create CMS Page
+ * 2. Create subcategory
+ * 3. Create simple product
+ *
+ * Steps:
+ * 1. Login to backend as Admin
+ * 2. Go to the Marketing-> SEO & Search->URL Redirects
+ * 3. Click "Add Url Rewrite" button
+ * 4. Select "Custom" in Create URL Rewrite dropdown
+ * 5. Fill data according to data set
+ * 6. Save Rewrite
+ * 7. Perform all assertions
+ *
+ * @group URL_Rewrites_(PS)
+ * @ZephyrId MTA-334
+ */
+class CreateCustomUrlRewriteEntityTest extends Injectable
+{
+    /**
+     * Url rewrite index page
+     *
+     * @var UrlrewriteIndex
+     */
+    protected $urlRewriteIndex;
+
+    /**
+     * Url rewrite edit page
+     *
+     * @var UrlrewriteEdit
+     */
+    protected $urlRewriteEdit;
+
+    /**
+     * Inject pages
+     *
+     * @param UrlrewriteIndex $urlRewriteIndex
+     * @param UrlrewriteEdit $urlRewriteEdit
+     * @return void
+     */
+    public function __inject(UrlrewriteIndex $urlRewriteIndex, UrlrewriteEdit $urlRewriteEdit)
+    {
+        $this->urlRewriteIndex = $urlRewriteIndex;
+        $this->urlRewriteEdit = $urlRewriteEdit;
+    }
+
+    /**
+     * Create custom URL Rewrite
+     *
+     * @param UrlRewrite $urlRewrite
+     * @return void
+     */
+    public function test(UrlRewrite $urlRewrite)
+    {
+        $this->urlRewriteIndex->open();
+        $this->urlRewriteIndex->getPageActionsBlock()->addNew();
+        $this->urlRewriteEdit->getUrlRewriteTypeSelectorBlock()->selectType('Custom');
+        $this->urlRewriteEdit->getFormBlock()->fill($urlRewrite);
+        $this->urlRewriteEdit->getPageMainActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv
new file mode 100644
index 0000000000000000000000000000000000000000..7d2ee52bbb1c44f8363156e16f3f0a740521509c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/TestCase/CreateCustomUrlRewriteEntityTest/test.csv
@@ -0,0 +1,5 @@
+"urlRewrite/data/id_path/entity";"urlRewrite/data/request_path";"urlRewrite/data/options";"urlRewrite/data/description";"constraint"
+"category/%catalogCategory::default_subcategory%";"category_request_path%isolation%";"Permanent (301)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
+"product/%catalogProductSimple::default%";"product_request_path%isolation%";"Temporary (302)";"test_description_relative path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
+"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"No";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
+"cms_page/%cmsPage::cms-page-test%";"cms_page_request_path%isolation%";"Temporary (302)";"test description_full path";"assertUrlRewriteSaveMessage, assertUrlRewriteInGrid, assertUrlRewriteCustomRedirect"
diff --git a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
index cba450836dead5a8d33fa44a8cda5badd4038892..fd070420677a58039dd0d8a7fca10fb194804c92 100644
--- a/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/UrlRewrite/Test/etc/global/constraint.xml
@@ -75,4 +75,7 @@
             <browser class="Mtf\Client\Browser"/>
         </require>
     </assertUrlRewriteCmsPageRedirect>
+    <assertUrlRewriteCustomRedirect module="Magento_UrlRewrite">
+        <severeness>low</severeness>
+    </assertUrlRewriteCustomRedirect>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/RoleForm.xml b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/RoleForm.xml
index acbd9cd481f0e015d4a9386a35016ecc94b1e1be..b823f3cef28e0a1fec021bcb2a6171f96f8380a2 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/RoleForm.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/RoleForm.xml
@@ -42,7 +42,7 @@
         <fields>
             <resource_access>
                 <input>select</input>
-                <selector>#all</selector>
+                <selector>[name="all"]</selector>
                 <strategy>css selector</strategy>
             </resource_access>
             <roles_resources>
@@ -52,4 +52,9 @@
             </roles_resources>
         </fields>
     </role-resources>
+    <in_role_users>
+        <class>\Magento\User\Test\Block\Adminhtml\Role\Tab\Role</class>
+        <selector>#role_info_tabs_roles</selector>
+        <strategy>css selector</strategy>
+    </in_role_users>
 </tabs>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/Role.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/Role.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a880eda3e9af03f409782992350ef6bfc0e14b6
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/Role.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Block\Adminhtml\Role\Tab;
+
+use Magento\Backend\Test\Block\Widget\Tab;
+use Mtf\Client\Element;
+
+/**
+ * Class Role
+ * Respond for filing data in roles users tab
+ */
+class Role extends Tab
+{
+    /**
+     * Fills username in user grid
+     *
+     * @param array $fields
+     * @param Element $element
+     * @return void
+     */
+    public function fillFormTab(array $fields, Element $element = null)
+    {
+        $users = (is_array($fields['in_role_users']['value']))
+            ? $fields['in_role_users']['value']
+            : [$fields['in_role_users']['value']];
+        foreach ($users as $user) {
+            $this->getUserGrid()->searchAndSelect(['username' => $user]);
+        }
+    }
+
+    /**
+     * Returns user grid block
+     *
+     * @return \Magento\User\Test\Block\Adminhtml\Role\Tab\User\Grid
+     */
+    public function getUserGrid()
+    {
+        return $this->blockFactory->create(
+            'Magento\User\Test\Block\Adminhtml\Role\Tab\User\Grid',
+            ['element' => $this->_rootElement->find('#roleUserGrid')]
+        );
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/User/Grid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/User/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..612e65af140f8c0dcfc27b56e745a871a2b8a1a6
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/Role/Tab/User/Grid.php
@@ -0,0 +1,52 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Block\Adminhtml\Role\Tab\User;
+
+use Magento\Backend\Test\Block\Widget\Grid as AbstractGrid;
+
+/**
+ * Class Grid
+ * Users grid in roles users tab
+ */
+class Grid extends AbstractGrid
+{
+    /**
+     * Grid filters' selectors
+     *
+     * @var array
+     */
+    protected $filters = [
+        'username' => [
+            'selector' => 'input[name="role_user_username"]'
+        ]
+    ];
+
+    /**
+     * Locator value for role name column
+     *
+     * @var string
+     */
+    protected $selectItem = '.col-in_role_users > input';
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role.php
index 0840ad4dcd348819d50c732f0ddc2254888b5555..8e58e9766456fe258d6315197c9903147134c646 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role.php
@@ -43,7 +43,7 @@ class Role extends Tab
      */
     public function fillFormTab(array $fields, Element $element = null)
     {
-        $this->getRoleGrid()->searchAndOpen(['rolename' => $fields['rolename']]);
+        $this->getRoleGrid()->searchAndSelect(['rolename' => $fields['role_id']['value']]);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role/Grid.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role/Grid.php
index 425921593c6babd35a88f468ebde7880049fd422..7868073a41193eacaee5395cae95afbae2eb5f81 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role/Grid.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/Tab/Role/Grid.php
@@ -49,5 +49,5 @@ class Grid extends GridInterface
      *
      * @var string
      */
-    protected $editLink = '.col-role_name';
+    protected $selectItem = '.col-assigned_user_role > input';
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.php b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.php
index 2634be773d6d40916874bd5d71bafb4f5547413f..adb591dc828e344c89c2dfa2fc0ffd59d81df5f7 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Block/Adminhtml/User/UserForm.php
@@ -25,9 +25,6 @@
 namespace Magento\User\Test\Block\Adminhtml\User;
 
 use Magento\Backend\Test\Block\Widget\FormTabs;
-use Magento\User\Test\Fixture\AdminUserInjectable;
-use Magento\User\Test\Fixture\AdminUserRole;
-use Mtf\Client\Element;
 
 /**
  * Class Edit
@@ -35,21 +32,5 @@ use Mtf\Client\Element;
  */
 class UserForm extends FormTabs
 {
-    /**
-     * Method for filling different fixtures' data on different tabs
-     *
-     * @param AdminUserInjectable $user
-     * @param null|AdminUserRole $role
-     */
-    public function fillUser(AdminUserInjectable $user, AdminUserRole $role = null)
-    {
-        if ($user->hasData()) {
-            parent::fill($user);
-        }
-        if ($role != null) {
-            $this->openTab('user-role');
-            $tabElement = $this->getTabElement('user-role');
-            $tabElement->fillFormTab(['rolename' => $role->getRoleName()]);
-        }
-    }
+    //
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php
index 409cd44af972ab843ac5faf7fd8c8f0615bd806c..846efe9f8c03083e01dce1c4b7b51a841dacafbb 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertRoleInGrid.php
@@ -45,17 +45,19 @@ class AssertRoleInGrid extends AbstractConstraint
      *
      * @param UserRoleIndex $rolePage
      * @param AdminUserRole $role
+     * @param AdminUserRole $roleInit
      * @return void
      */
     public function processAssert(
         UserRoleIndex $rolePage,
-        AdminUserRole $role
+        AdminUserRole $role,
+        AdminUserRole $roleInit = null
     ) {
-        $filter = ['rolename' => $role->getRoleName()];
+        $filter = ['rolename' => $role->hasData('rolename') ? $role->getRoleName() : $roleInit->getRoleName()];
         $rolePage->open();
         \PHPUnit_Framework_Assert::assertTrue(
             $rolePage->getRoleGrid()->isRowVisible($filter),
-            'Role with name \'' . $role->getRoleName() . '\' is absent in Roles grid.'
+            'Role with name \'' . $filter['rolename'] . '\' is absent in Roles grid.'
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserDuplicateMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserDuplicateMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..369b32a0503ee7d9307020571dd7115d11f5498c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserDuplicateMessage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+
+/**
+ * Class AssertUserDuplicateMessage
+ */
+class AssertUserDuplicateMessage extends AbstractConstraint
+{
+    const ERROR_MESSAGE = 'A user with the same user name or email already exists.';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that error message equals to expected message.
+     *
+     * @param UserEdit $userEdit
+     * @return void
+     */
+    public function processAssert(UserEdit $userEdit)
+    {
+        $failedMessage = $userEdit->getMessagesBlock()->getErrorMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            self::ERROR_MESSAGE,
+            $failedMessage,
+            'Wrong success message is displayed.'
+            . "\nExpected: " . self::ERROR_MESSAGE
+            . "\nActual: " . $failedMessage
+        );
+    }
+
+    /**
+     * Returns success message if assert true.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Error message on creation user page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php
index eddf99452a39575c7b64da2ab85b87ea58c8c060..d3c5fc94f03671c91260b19c1a6ddcc993197dae 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInGrid.php
@@ -24,7 +24,7 @@
 
 namespace Magento\User\Test\Constraint;
 
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\User\Test\Page\Adminhtml\UserIndex;
 
@@ -44,14 +44,14 @@ class AssertUserInGrid extends AbstractConstraint
      * Asserts that user is present in User Grid.
      *
      * @param UserIndex $userIndex
-     * @param AdminUserInjectable $user
-     * @param AdminUserInjectable $customAdmin
+     * @param User $user
+     * @param User $customAdmin
      * @return void
      */
     public function processAssert(
         UserIndex $userIndex,
-        AdminUserInjectable $user,
-        AdminUserInjectable $customAdmin = null
+        User $user,
+        User $customAdmin = null
     ) {
         $adminUser = ($user->hasData('password') || $user->hasData('username')) ? $user : $customAdmin;
         $filter = ['username' => $adminUser->getUsername()];
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInvalidEmailMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInvalidEmailMessage.php
new file mode 100644
index 0000000000000000000000000000000000000000..096b41bd312aeb56986972ba7fa75e566f79f1b5
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserInvalidEmailMessage.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Constraint;
+
+use Mtf\Constraint\AbstractConstraint;
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+use Magento\User\Test\Fixture\User;
+
+/**
+ * Class AssertUserInvalidEmailMessage
+ */
+class AssertUserInvalidEmailMessage extends AbstractConstraint
+{
+    const ERROR_MESSAGE = 'Please correct this email address: "%s".';
+
+    /**
+     * Constraint severeness
+     *
+     * @var string
+     */
+    protected $severeness = 'low';
+
+    /**
+     * Asserts that error message equals to expected message.
+     *
+     * @param UserEdit $userEdit
+     * @param User $user
+     * @return void
+     */
+    public function processAssert(UserEdit $userEdit, User $user)
+    {
+        $expectedMessage = sprintf(self::ERROR_MESSAGE, $user->getEmail());
+        $actualMessage = $userEdit->getMessagesBlock()->getErrorMessages();
+        \PHPUnit_Framework_Assert::assertEquals(
+            $expectedMessage,
+            $actualMessage,
+            'Wrong error message is displayed.'
+            . "\nExpected: " . $expectedMessage
+            . "\nActual: " . $actualMessage
+        );
+    }
+
+    /**
+     * Returns message if equals to expected message.
+     *
+     * @return string
+     */
+    public function toString()
+    {
+        return 'Error message about invalid email on creation user page is correct.';
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php
index 19056cdf4c199620c9c9d24af902fac16378946c..6fae96645646cc2cb9588c6dfa48c1ea909c4386 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserNotInGrid.php
@@ -25,7 +25,7 @@
 namespace Magento\User\Test\Constraint;
 
 use Mtf\Constraint\AbstractConstraint;
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Magento\User\Test\Page\Adminhtml\UserIndex;
 
 /**
@@ -44,12 +44,12 @@ class AssertUserNotInGrid extends AbstractConstraint
      * Asserts that User is not present in User Grid.
      *
      * @param UserIndex $userIndex
-     * @param AdminUserInjectable $adminUser
+     * @param User $adminUser
      * @return void
      */
     public function processAssert(
         UserIndex $userIndex,
-        AdminUserInjectable $adminUser
+        User $adminUser
     ) {
         $filter = ['username' => $adminUser->getUsername()];
         $userIndex->open();
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleSalesRestrictedAccess.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleSalesRestrictedAccess.php
index 27318ba2ee0ad4bc28790ea15b6ae88681a0c2c8..fde7fdf4d8f6e146677ec2d4c3d6fd0d388cd603 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleSalesRestrictedAccess.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserRoleSalesRestrictedAccess.php
@@ -57,10 +57,11 @@ class AssertUserRoleSalesRestrictedAccess extends AbstractConstraint
         $menuItems = $dashboard->getMenuBlock()->getTopMenuItems();
         $userIndex->open();
         $deniedMessage = $userIndex->getAccessDeniedBlock()->getTextFromAccessDeniedBlock();
-        $hasSales = (in_array(self::ROLE_RESOURCE, $menuItems) && count($menuItems) == 1) ? true : false;
+        $isMenuItemSingle = (count($menuItems) == 1);
+        $hasSales = in_array(self::ROLE_RESOURCE, $menuItems);
         \PHPUnit_Framework_Assert::assertTrue(
-            $hasSales && self::DENIED_ACCESS == $deniedMessage,
-            'Sales item is absent in Menu block.'
+            $hasSales && $isMenuItemSingle && (self::DENIED_ACCESS == $deniedMessage),
+            'Sales item is absent in Menu block or possible access to another page, not related to Sales.'
         );
     }
 
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogOut.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogOut.php
index 456792d088b5461d75b6ef1fd2accc7f276e1b14..f28c256c9a50086bf3b28e0d775dde432a97fc15 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogOut.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogOut.php
@@ -66,6 +66,6 @@ class AssertUserSuccessLogOut extends AbstractConstraint
      */
     public function toString()
     {
-        return 'User had successfully logout.';
+        return 'User had successfully logged out.';
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogin.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogin.php
index c4da03406ffb8042cceb6fd871e53634db57da91..ec153d57da0ce87e83528d3e68a7375c392bb758 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogin.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserSuccessLogin.php
@@ -24,7 +24,7 @@
 
 namespace Magento\User\Test\Constraint;
 
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\Backend\Test\Page\Dashboard;
 use Magento\Backend\Test\Page\AdminAuthLogin;
@@ -44,19 +44,20 @@ class AssertUserSuccessLogin extends AbstractConstraint
     /**
      * Verify whether customer has logged in to the Backend
      *
-     * @param Dashboard $dashboard
-     * @param AdminUserInjectable $user
+     * @param User $user
      * @param AdminAuthLogin $adminAuth
-     * @param AdminUserInjectable $customAdmin
+     * @param Dashboard $dashboard
+     * @param User $customAdmin
+     * @internal param null|string $userToLoginInAssert
      * @return void
      */
     public function processAssert(
-        Dashboard $dashboard,
-        AdminUserInjectable $user,
+        User $user,
         AdminAuthLogin $adminAuth,
-        AdminUserInjectable $customAdmin = null
+        Dashboard $dashboard,
+        User $customAdmin = null
     ) {
-        $adminUser = ($user->hasData('password') || $user->hasData('username')) ? $user : $customAdmin;
+        $adminUser = $customAdmin === null ? $user : $customAdmin;
         if ($dashboard->getAdminPanelHeader()->isVisible()) {
             $dashboard->getAdminPanelHeader()->logOut();
         }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserWrongCredentialsMessage.php b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserWrongCredentialsMessage.php
index e1a7702e5bbcdff190e0f564256a59f4b23b36aa..31054f60439181eefc1b03501ffec4c1bc5c5b68 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserWrongCredentialsMessage.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Constraint/AssertUserWrongCredentialsMessage.php
@@ -24,7 +24,7 @@
 
 namespace Magento\User\Test\Constraint;
 
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Mtf\Constraint\AbstractConstraint;
 use Magento\Backend\Test\Page\AdminAuthLogin;
 
@@ -46,12 +46,12 @@ class AssertUserWrongCredentialsMessage extends AbstractConstraint
      * Verify incorrect credentials message while login to admin
      *
      * @param AdminAuthLogin $adminAuth
-     * @param AdminUserInjectable $customAdmin
+     * @param User $customAdmin
      * @return void
      */
     public function processAssert(
         AdminAuthLogin $adminAuth,
-        AdminUserInjectable $customAdmin
+        User $customAdmin
     ) {
         $adminAuth->open();
         $adminAuth->getLoginBlock()->fill($customAdmin);
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php
index 44ca844e6adb22d85e056d2d584168309fac498f..99631a7758fcb17a2d8363e7c438a099066100ac 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.php
@@ -100,6 +100,7 @@ class AdminUserRole extends InjectableFixture
         'is_required' => '',
         'default_value' => '',
         'input' => '',
+        'group' => 'role-info'
     ];
 
     protected $user_type = [
@@ -113,11 +114,20 @@ class AdminUserRole extends InjectableFixture
     protected $resource_access = [
         'attribute_code' => 'resource_access',
         'backend_type' => 'virtual',
+        'group' => 'role-resources'
     ];
 
     protected $roles_resources = [
         'attribute_code' => 'roles_resources',
         'backend_type' => 'virtual',
+        'group' => 'role-resources'
+    ];
+
+    protected $in_role_users = [
+        'attribute_code' => 'in_role_users',
+        'backend_type' => 'virtual',
+        'group' => 'in_role_users',
+        'source' => 'Magento\User\Test\Fixture\AdminUserRole\InRoleUsers',
     ];
 
     public function getRoleId()
@@ -184,4 +194,9 @@ class AdminUserRole extends InjectableFixture
     {
         return $this->getData('roles_resources');
     }
+
+    public function getInRoleUsers()
+    {
+        return $this->getData('in_role_users');
+    }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml
index 0dddfdbd20ec25fb4e55b3b1e4f55a4918298029..62ec17b4b56b3ae0370b981cd170f23fd9c02b06 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole.xml
@@ -93,6 +93,12 @@
             <attribute_code>roles_resources</attribute_code>
             <backend_type>virtual</backend_type>
         </roles_resources>
+        <in_role_users>
+            <attribute_code>in_role_users</attribute_code>
+            <backend_type>virtual</backend_type>
+            <group>in_role_users</group>
+            <source>Magento\User\Test\Fixture\AdminUserRole\InRoleUsers</source>
+        </in_role_users>
     </fields>
     <repository_class>Magento\User\Test\Repository\AdminUserRole</repository_class>
     <handler_interface>Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface</handler_interface>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole/InRoleUsers.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole/InRoleUsers.php
new file mode 100644
index 0000000000000000000000000000000000000000..59af9852ced4bdcb94db0fb426d9144bb8789fab
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserRole/InRoleUsers.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\Fixture\AdminUserRole;
+
+use Mtf\Fixture\FixtureFactory;
+use Mtf\Fixture\FixtureInterface;
+use Mtf\Util\Protocol\CurlTransport;
+use Magento\User\Test\Fixture\User;
+
+/**
+ * Class InRoleUsers
+ *
+ * Data keys:
+ *  - dataSet
+ */
+class InRoleUsers implements FixtureInterface
+{
+    /**
+     * Array with data set configuration settings
+     *
+     * @var array
+     */
+    protected $params;
+
+    /**
+     * Array with Admin Users
+     *
+     * @var array
+     */
+    protected $adminUsers;
+
+    /**
+     * Array with usernames
+     *
+     * @var array
+     */
+    protected $data;
+
+    /**
+     * @construct
+     * @param FixtureFactory $fixtureFactory
+     * @param array $params
+     * @param array $data
+     */
+    public function __construct(FixtureFactory $fixtureFactory, array $params, array $data = [])
+    {
+        $this->params = $params;
+        if (isset($data['dataSet']) && $data['dataSet'] !== '-') {
+            $dataSets = explode(',', $data['dataSet']);
+            foreach ($dataSets as $dataSet) {
+                $adminUser = $fixtureFactory->createByCode('user', ['dataSet' => trim($dataSet)]);
+                if (!$adminUser->hasData('user_id')) {
+                    $adminUser->persist();
+                }
+                $this->adminUsers[] = $adminUser;
+                $this->data[] = $adminUser->getUsername();
+            }
+        }
+    }
+
+    /**
+     * Persist user role
+     *
+     * @return void
+     */
+    public function persist()
+    {
+        //
+    }
+
+    /**
+     * Return array with usernames
+     *
+     * @param string $key [optional]
+     * @return array|null
+     *
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function getData($key = null)
+    {
+        return $this->data;
+    }
+
+    /**
+     * Return data set configuration settings
+     *
+     * @return array
+     */
+    public function getDataConfig()
+    {
+        return $this->params;
+    }
+
+    /**
+     * Return array with admin user fixtures
+     *
+     * @return array
+     */
+    public function getAdminUsers()
+    {
+        return $this->adminUsers;
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
similarity index 93%
rename from dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
index f6e96d1cdf0ad370fdf5d691b0ef6161def96586..4b3699c2d067bcc593de9cc3d8eed3750b64a151 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.php
@@ -27,21 +27,21 @@ namespace Magento\User\Test\Fixture;
 use Mtf\Fixture\InjectableFixture;
 
 /**
- * Class AdminUserInjectable
+ * Class User
  *
  * @SuppressWarnings(PHPMD.TooManyFields)
  */
-class AdminUserInjectable extends InjectableFixture
+class User extends InjectableFixture
 {
     /**
      * @var string
      */
-    protected $repositoryClass = 'Magento\User\Test\Repository\AdminUserInjectable';
+    protected $repositoryClass = 'Magento\User\Test\Repository\User';
 
     /**
      * @var string
      */
-    protected $handlerInterface = 'Magento\User\Test\Handler\AdminUser\AdminUserInterface';
+    protected $handlerInterface = 'Magento\User\Test\Handler\User\UserInterface';
 
     protected $defaultDataSet = [
         'username' => 'AdminUser%isolation%',
@@ -188,12 +188,8 @@ class AdminUserInjectable extends InjectableFixture
     protected $role_id = [
         'attribute_code' => 'role_id',
         'backend_type' => 'virtual',
-    ];
-
-    protected $role = [
-        'attribute_code' => 'role',
-        'backend_type' => 'virtual',
-        'source' => 'Magento\User\Test\Fixture\User\Role'
+        'group' => 'user-role',
+        'source' => 'Magento\User\Test\Fixture\User\RoleId'
     ];
 
     protected $password_confirmation = [
@@ -287,11 +283,6 @@ class AdminUserInjectable extends InjectableFixture
         return $this->getData('role_id');
     }
 
-    public function getRole()
-    {
-        return $this->getData('role');
-    }
-
     public function getPasswordConfirmation()
     {
         return $this->getData('password_confirmation');
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.xml b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
similarity index 94%
rename from dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.xml
rename to dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
index fc51e9fefc3814f7c982f2a80e8dd7d2d75b187d..2945e1bb245c405e65401b8aa43225cb61aefe8d 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/AdminUserInjectable.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User.xml
@@ -23,7 +23,7 @@
  * @license     http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
  */
 -->
-<fixture class="Magento\User\Test\Fixture\AdminUserInjectable">
+<fixture class="Magento\User\Test\Fixture\User">
     <module>Magento_User</module>
     <type>flat</type>
     <entity_type>admin_user</entity_type>
@@ -144,12 +144,14 @@
         <role_id>
             <attribute_code>role_id</attribute_code>
             <backend_type>virtual</backend_type>
+            <group>user-role</group>
+            <source>Magento\User\Test\Fixture\User\RoleId</source>
         </role_id>
         <password_confirmation>
             <attribute_code>password_confirmation</attribute_code>
             <backend_type>virtual</backend_type>
         </password_confirmation>
     </fields>
-    <repository_class>Magento\User\Test\Repository\AdminUserInjectable</repository_class>
-    <handler_interface>Magento\User\Test\Handler\AdminUser\AdminUserInterface</handler_interface>
+    <repository_class>Magento\User\Test\Repository\User</repository_class>
+    <handler_interface>Magento\User\Test\Handler\User\UserInterface</handler_interface>
 </fixture>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/Role.php b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/RoleId.php
similarity index 88%
rename from dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/Role.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/RoleId.php
index 08a765caf2641712664f8bb7e6cc616065c5b271..45705e1562a4707cd38b7a26346bda848a5ddc7d 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/Role.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Fixture/User/RoleId.php
@@ -30,12 +30,13 @@ use Mtf\Util\Protocol\CurlTransport;
 use Magento\User\Test\Fixture\AdminUserRole;
 
 /**
- * Class Role
+ * Class RoleId
  *
  * Data keys:
  *  - dataSet
+ *  - role
  */
-class Role implements FixtureInterface
+class RoleId implements FixtureInterface
 {
     /**
      * Admin User Role
@@ -67,11 +68,9 @@ class Role implements FixtureInterface
             }
             $this->data = $this->role->getRoleName();
         }
-        if (isset($data['role_fixture'])
-            && $data['role_fixture'] instanceof \Magento\User\Test\Fixture\AdminUserRole
-        ) {
-            $this->role = $data['role_fixture'];
-            $this->data = $data['role_fixture']->getRoleName();
+        if (isset($data['role']) && $data['role'] instanceof AdminUserRole) {
+            $this->role = $data['role'];
+            $this->data = $data['role']->getRoleName();
         }
     }
 
@@ -101,7 +100,7 @@ class Role implements FixtureInterface
     /**
      * Return data set configuration settings
      *
-     * @return string
+     * @return array
      */
     public function getDataConfig()
     {
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
index a35a2feb403aa9514c7f5610f3dd2a767fec5551..e5479d2d5d54168308e01e7a26359df63f59da35 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUserRole/Curl.php
@@ -44,6 +44,8 @@ class Curl extends AbstractCurl implements AdminUserRoleInterface
      * @param FixtureInterface $fixture
      * @return array|mixed
      * @throws \Exception
+     *
+     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function persist(FixtureInterface $fixture = null)
     {
@@ -56,6 +58,14 @@ class Curl extends AbstractCurl implements AdminUserRoleInterface
         }
         unset($data['roles_resources']);
         $data['gws_is_all'] = (isset($data['gws_is_all'])) ? $data['gws_is_all'] : '1';
+        if ($fixture->hasData('in_role_user')) {
+            $adminUsers = $fixture->getDataFieldConfig('in_role_user')['source']->getAdminUsers();
+            $userIds = [];
+            foreach ($adminUsers as $adminUser) {
+                $userIds[] = $adminUser->getUserId() . "=true";
+            }
+            $data['in_role_user'] = implode('&', $userIds);
+        }
         $url = $_ENV['app_backend_url'] . 'admin/user_role/saverole/active_tab/info/';
         $curl = new BackendDecorator(new CurlTransport(), new Config);
         $curl->addOption(CURLOPT_HEADER, 1);
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
similarity index 88%
rename from dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
index d91467f1d1589d32246102ad04b48bfe1d7c4256..f83b32cd87f01493c8009d1c5615b0576c41a351 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/Curl.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/Curl.php
@@ -22,7 +22,7 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\User\Test\Handler\AdminUser;
+namespace Magento\User\Test\Handler\User;
 
 use Mtf\Fixture\FixtureInterface;
 use Mtf\Handler\Curl as AbstractCurl;
@@ -36,7 +36,7 @@ use Magento\Backend\Test\Handler\Extractor;
  * Class Curl
  * Creates Admin User Entity
  */
-class Curl extends AbstractCurl implements AdminUserInterface
+class Curl extends AbstractCurl implements UserInterface
 {
     /**
      * Curl creation of Admin User
@@ -47,11 +47,11 @@ class Curl extends AbstractCurl implements AdminUserInterface
      */
     public function persist(FixtureInterface $fixture = null)
     {
-        /** @var \Magento\User\Test\Fixture\AdminUserInjectable $fixture */
+        /** @var \Magento\User\Test\Fixture\User $fixture */
         $data = $fixture->getData();
-        $role = $fixture->getDataFieldConfig('role')['source']->getRole();
-        $data['roles[]'] = $role->getRoleId();
-
+        if ($fixture->hasData('role_id')) {
+            $data['roles[]'] = $fixture->getDataFieldConfig('role_id')['source']->getRole()->getRoleId();
+        }
         $url = $_ENV['app_backend_url'] . 'admin/user/save/active_tab/main_section/';
         $curl = new BackendDecorator(new CurlTransport(), new Config);
         $curl->addOption(CURLOPT_HEADER, 1);
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/AdminUserInterface.php b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/UserInterface.php
similarity index 87%
rename from dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/AdminUserInterface.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Handler/User/UserInterface.php
index efc58626423be2a58201b3673ab5b60194c5f533..04ae7a1971113114672ee51bb81f85fb67e62cf6 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Handler/AdminUser/AdminUserInterface.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Handler/User/UserInterface.php
@@ -22,14 +22,14 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\User\Test\Handler\AdminUser;
+namespace Magento\User\Test\Handler\User;
 
 use Mtf\Handler\HandlerInterface;
 
 /**
- * Interface AdminUserInterface
+ * Interface UserInterface
  */
-interface AdminUserInterface extends HandlerInterface
+interface UserInterface extends HandlerInterface
 {
     //
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php
index d8435f0fb8964c87c2bddad754dc1ec83f1110a1..579dcc12f167654367b4839c2de73e4079b7c571 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Page/Adminhtml/UserRoleIndex.php
@@ -31,7 +31,7 @@ use Mtf\Page\BackendPage;
  */
 class UserRoleIndex extends BackendPage
 {
-    const MCA = 'admin/user_role/index';
+    const MCA = 'admin/user_role';
 
     protected $_blocks = [
         'roleActions' => [
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
index d90b6e5b64af5e15153cae4172a8091c393a7bed..81006f28aa7a607f489da607317dcf1b947a9496 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserRole.php
@@ -46,6 +46,12 @@ class AdminUserRole extends AbstractRepository
             'resource_access' => 'All'
         ];
 
+        $this->_data['Administrators'] = [
+            'rolename' => 'Administrators',
+            'resource_access' => 'All',
+            'role_id' => 1,
+        ];
+
         $this->_data['role_sales'] = [
             'rolename' => 'RoleName%isolation%',
             'resource_access' => 'Custom',
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php b/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
similarity index 93%
rename from dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php
rename to dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
index f1f19188669e798b15ecdecb157d41f97d8707b8..fd01fe32638a978a39ed5534c8189304ca3ca2fa 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/Repository/AdminUserInjectable.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/Repository/User.php
@@ -27,10 +27,10 @@ namespace Magento\User\Test\Repository;
 use Mtf\Repository\AbstractRepository;
 
 /**
- * Class AdminUserInjectable
- * Admin User Repository
+ * Class User
+ * User Repository
  */
-class AdminUserInjectable extends AbstractRepository
+class User extends AbstractRepository
 {
     /**
      * @constructor
@@ -67,7 +67,7 @@ class AdminUserInjectable extends AbstractRepository
             'email' => 'email%isolation%@example.com',
             'password' => '123123q',
             'password_confirmation' => '123123q',
-            'role' => ['dataSet' => 'default']
+            'role_id' => ['dataSet' => 'default']
         ];
     }
 }
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..239ee6aebd5a01cacc109945f52fbc8fa110e020
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\TestCase;
+
+use Magento\User\Test\Fixture\User;
+use Magento\User\Test\Page\Adminhtml\UserEdit;
+use Magento\User\Test\Page\Adminhtml\UserIndex;
+use Mtf\Fixture\FixtureFactory;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for CreateAdminUserEntityTest
+ *
+ * Test Flow:
+ * 1. Log in as default admin user
+ * 2. Go to System-Permissions-All Users
+ * 3. Press "+" button to start create new admin user
+ * 4. Fill in all data according to data set
+ * 5. Save user
+ * 6. Perform assertions
+ *
+ * @group ACL_(MX)
+ * @ZephyrId MAGETWO-21338
+ */
+class CreateAdminUserEntityTest extends Injectable
+{
+    /**
+     * User grid page
+     *
+     * @var UserIndex
+     */
+    protected $userIndexPage;
+
+    /**
+     * User new/edit page
+     *
+     * @var UserEdit
+     */
+    protected $userEditPage;
+
+    /**
+     * Factory for Fixtures
+     *
+     * @var FixtureFactory
+     */
+    protected $fixtureFactory;
+
+    /**
+     * Preconditions for test
+     *
+     * @param FixtureFactory $fixtureFactory
+     * @return array
+     */
+    public function __prepare(FixtureFactory $fixtureFactory)
+    {
+        $this->fixtureFactory = $fixtureFactory;
+        $adminUser = $fixtureFactory->createByCode('user');
+        $adminUser->persist();
+
+        return ['adminUser' => $adminUser];
+    }
+
+    /**
+     * Setup necessary data for test
+     *
+     * @param UserIndex $userIndex
+     * @param UserEdit $userEdit
+     * @return void
+     */
+    public function __inject(
+        UserIndex $userIndex,
+        UserEdit $userEdit
+    ) {
+        $this->userIndexPage = $userIndex;
+        $this->userEditPage = $userEdit;
+    }
+
+    /**
+     * @param User $user
+     * @param User $adminUser
+     * @param string $isDuplicated
+     * @return void
+     */
+    public function test(
+        User $user,
+        User $adminUser,
+        $isDuplicated
+    ) {
+        // Prepare data
+        if ($isDuplicated != '-') {
+            $data = $user->getData();
+            $data[$isDuplicated] = $adminUser->getData($isDuplicated);
+            $data['role_id'] = ['role' => $user->getDataFieldConfig('role_id')['source']->getRole()];
+            $user = $this->fixtureFactory->createByCode('user', ['data' => $data]);
+        }
+
+        // Steps
+        $this->userIndexPage->open();
+        $this->userIndexPage->getPageActions()->addNew();
+        $this->userEditPage->getUserForm()->fill($user);
+        $this->userEditPage->getPageActions()->save();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv
new file mode 100644
index 0000000000000000000000000000000000000000..ec5ef067904c23493bc266b88f450c6962f83d22
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserEntityTest/test.csv
@@ -0,0 +1,7 @@
+"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"isDuplicated";"constraint"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Inactive";"Administrators";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
+"-";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"Administrators";"username";"assertUserDuplicateMessage"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"-";"123123q";"123123q";"Active";"Administrators";"email";"assertUserDuplicateMessage"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.com";"123123q";"123123q";"Active";"-";"-";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
+"AdminUser%isolation%";"FirstName%isolation%";"LastName%isolation%";"email%isolation%@example.cim";"123123q";"123123q";"Active";"-";"-";"assertUserInvalidEmailMessage"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php
index 796adf8faf3ec0537d4389b766586107a0a6b1e7..ee52205fcdf6678ab607c5cd6c55d73ebe6e557b 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/CreateAdminUserRoleEntityTest.php
@@ -56,6 +56,8 @@ class CreateAdminUserRoleEntityTest extends Injectable
     protected $userRoleEditRole;
 
     /**
+     * Setup data for test
+     *
      * @param UserRoleIndex $userRoleIndex
      * @param UserRoleEditRole $userRoleEditRole
      */
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php
index 1d6c66d84ea419c4a56f2d21e51d681b1da8e7c6..025957a13f0f59253e99397ddb805401d67196db 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteAdminUserEntityTest.php
@@ -29,7 +29,7 @@ use Magento\Backend\Test\Page\Dashboard;
 use Magento\User\Test\Page\Adminhtml\UserEdit;
 use Magento\User\Test\Page\Adminhtml\UserIndex;
 use Mtf\TestCase\Injectable;
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Mtf\Fixture\FixtureFactory;
 
 /**
@@ -79,7 +79,7 @@ class DeleteAdminUserEntityTest extends Injectable
     public function __prepare(FixtureFactory $fixtureFactory)
     {
         $user = $fixtureFactory->createByCode(
-            'adminUserInjectable',
+            'user',
             ['dataSet' => 'custom_admin_with_default_role']
         );
         $user->persist();
@@ -113,12 +113,12 @@ class DeleteAdminUserEntityTest extends Injectable
     /**
      * Runs Delete User Entity test
      *
-     * @param AdminUserInjectable $user
+     * @param User $user
      * @param string $isDefaultUser
      * @return void
      */
     public function testDeleteAdminUserEntity(
-        AdminUserInjectable $user,
+        User $user,
         $isDefaultUser
     ) {
         $filter = [
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php
index 84af8af5af4117b0aa1049cb2f016bd618ef8406..6b4aa2d57f6970082944696fd2ba02afe0c6a0f2 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/DeleteUserRoleEntityTest.php
@@ -26,7 +26,7 @@ namespace Magento\User\Test\TestCase;
 
 use Magento\Backend\Test\Page\AdminAuthLogin;
 use Magento\Backend\Test\Page\Dashboard;
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Magento\User\Test\Fixture\AdminUserRole;
 use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
 use Magento\User\Test\Page\Adminhtml\UserRoleEditRole;
@@ -79,20 +79,14 @@ class DeleteUserRoleEntityTest extends Injectable
      */
     public function __prepare(FixtureFactory $fixtureFactory)
     {
-        /** @var \Magento\User\Test\Fixture\AdminUserRole  $role */
-        $role = $fixtureFactory->createByCode('adminUserRole', ['dataSet' => 'default']);
-        $role->persist();
         $adminUser = $fixtureFactory->createByCode(
-            'adminUserInjectable',
-            [
-                'dataSet' => 'custom_admin_with_default_role',
-                'data' => ['role' => ['role_fixture' => $role]],
-            ]
+            'user',
+            ['dataSet' => 'custom_admin_with_default_role']
         );
         $adminUser->persist();
 
         return [
-            'role' => $role,
+            'role' => $adminUser->getDataFieldConfig('role_id')['source']->getRole(),
             'adminUser' => $adminUser
         ];
     }
@@ -120,13 +114,13 @@ class DeleteUserRoleEntityTest extends Injectable
      * Runs Delete User Role Entity test.
      *
      * @param AdminUserRole $role
-     * @param AdminUserInjectable $adminUser
+     * @param User $adminUser
      * @param string $isDefaultUser
      * @return void
      */
     public function testDeleteAdminUserRole(
         AdminUserRole $role,
-        AdminUserInjectable $adminUser,
+        User $adminUser,
         $isDefaultUser
     ) {
         $filter = [
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest.php
deleted file mode 100644
index 4ae2844d471d354fa0d3bb3b750c73111657f302..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest.php
+++ /dev/null
@@ -1,79 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\User\Test\TestCase;
-
-use Mtf\TestCase\Injectable;
-use Magento\Backend\Test\Page\Dashboard;
-use Magento\Backend\Test\Page\AdminAuthLogin;
-use Magento\User\Test\Fixture\AdminUserInjectable;
-
-/**
- * Class LoginUserTest
- * Tests login to backend
- *
- */
-class LoginUserTest extends Injectable
-{
-    /**
-     * @var AdminAuthLogin
-     */
-    protected $loginPage;
-
-    /**
-     * @var Dashboard
-     */
-    protected $dashboard;
-
-    /**
-     * @param AdminAuthLogin $loginPage
-     * @param Dashboard $dashboard
-     */
-    public function __inject(AdminAuthLogin $loginPage, Dashboard $dashboard)
-    {
-        $this->loginPage = $loginPage;
-        $this->dashboard = $dashboard;
-    }
-
-    /**
-     * Log out if the admin user is already logged in.
-     */
-    protected function setUp()
-    {
-        $this->dashboard->getAdminPanelHeader()->logOut();
-    }
-
-    /**
-     * Test admin login to backend
-     *
-     * @param AdminUserInjectable $user
-     */
-    public function test(AdminUserInjectable $user)
-    {
-        // Steps
-        $this->loginPage->open();
-        $this->loginPage->getLoginBlock()->fill($user);
-        $this->loginPage->getLoginBlock()->submit();
-    }
-}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest/test.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest/test.csv
deleted file mode 100644
index 937e828197af3f45e459927f9204201fd7daa3b9..0000000000000000000000000000000000000000
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/LoginUserTest/test.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-"user/data/username"; "user/data/password"; "constraint"
-"admin"; "123123q"; "assertUserSuccessLogin"
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php
index 0e128b69f1c0601629fe887a953c160b74568a33..a7c99546e7d938ac192769b088d0357d84d06f70 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest.php
@@ -25,8 +25,7 @@
 namespace Magento\User\Test\TestCase;
 
 use Magento\Backend\Test\Page\AdminAuthLogin;
-use Magento\Cms\Test\Page\CmsIndex;
-use Magento\User\Test\Fixture\AdminUserInjectable;
+use Magento\User\Test\Fixture\User;
 use Magento\User\Test\Fixture\AdminUserRole;
 use Mtf\Fixture\FixtureFactory;
 use Mtf\TestCase\Injectable;
@@ -76,17 +75,9 @@ class UpdateAdminUserEntityTest extends Injectable
     protected $adminAuth;
 
     /**
-     * Run preconditions for test.
-     *
-     * @param FixtureFactory $fixtureFactory
-     * @return array
+     * @var FixtureFactory
      */
-    public function __prepare(FixtureFactory $fixtureFactory)
-    {
-        $roleSales = $fixtureFactory->createByCode('adminUserRole', ['dataSet' => 'role_sales']);
-        $roleSales->persist();
-        return ['roleSales' => $roleSales];
-    }
+    protected $fixtureFactory;
 
     /**
      * Setup necessary data for test
@@ -96,7 +87,7 @@ class UpdateAdminUserEntityTest extends Injectable
      * @param Dashboard $dashboard
      * @param AdminAuthLogin $adminAuth
      * @param FixtureFactory $fixtureFactory
-     * @return array
+     * @return void
      */
     public function __inject(
         UserIndex $userIndex,
@@ -109,49 +100,61 @@ class UpdateAdminUserEntityTest extends Injectable
         $this->userEdit = $userEdit;
         $this->dashboard = $dashboard;
         $this->adminAuth = $adminAuth;
-
-        $customAdmin = $fixtureFactory->createByCode(
-            'adminUserInjectable',
-            ['dataSet' => 'custom_admin_with_default_role']
-        );
-        $customAdmin->persist();
-
-        return [
-            'customAdmin' => $customAdmin
-        ];
+        $this->fixtureFactory = $fixtureFactory;
     }
 
     /**
      * Runs Update Admin User test
      *
-     * @param AdminUserInjectable $user
-     * @param AdminUserInjectable $customAdmin
-     * @param AdminUserRole $roleSales
-     * @param string $useSalesRoleFromDataSet
+     * @param User $user
+     * @param User $initialUser
      * @param string $loginAsDefaultAdmin
-     * @return void
+     * @return array
      */
     public function testUpdateAdminUser(
-        AdminUserInjectable $user,
-        AdminUserInjectable $customAdmin,
-        AdminUserRole $roleSales,
-        $useSalesRoleFromDataSet,
+        User $user,
+        User $initialUser,
         $loginAsDefaultAdmin
     ) {
-        // Prepare data
-        $filter = ['username' => $customAdmin->getUsername()];
-        $userRole = $useSalesRoleFromDataSet != '-' ? $roleSales : null;
+        // Precondition
+        $initialUser->persist();
 
         // Steps
+        $filter = ['username' => $initialUser->getUsername()];
         if ($loginAsDefaultAdmin == '0') {
             $this->adminAuth->open();
-            $this->adminAuth->getLoginBlock()->fill($customAdmin);
+            $this->adminAuth->getLoginBlock()->fill($initialUser);
             $this->adminAuth->getLoginBlock()->submit();
         }
         $this->userIndex->open();
         $this->userIndex->getUserGrid()->searchAndOpen($filter);
-        $this->userEdit->getUserForm()->fillUser($user, $userRole);
+        $this->userEdit->getUserForm()->fill($user);
         $this->userEdit->getPageActions()->save();
+
+        return ['customAdmin' => $this->mergeUsers($user, $initialUser)];
+    }
+
+    /**
+     * Merging user data and returns custom user
+     *
+     * @param User $user
+     * @param User $initialUser
+     * @return User
+     */
+    protected function mergeUsers(
+        User $user,
+        User $initialUser
+    ) {
+        $data = array_merge($initialUser->getData(), $user->getData());
+        if (isset($data['role_id'])) {
+            $data['role_id'] = [
+                'role' => ($user->hasData('role_id'))
+                    ? $user->getDataFieldConfig('role_id')['source']->getRole()
+                    : $initialUser->getDataFieldConfig('role_id')['source']->getRole()
+            ];
+        }
+
+        return $this->fixtureFactory->createByCode('user', ['data' => $data]);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
index 0ce0c1ca5f74a72d9e740fd355e2b38971a2277e..aef3614251b5ebc3d9b1a640dbba0924fd6bb33c 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserEntityTest/testUpdateAdminUser.csv
@@ -1,4 +1,4 @@
-"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"useSalesRoleFromDataSet";"loginAsDefaultAdmin";"constraint"
-"NewAdminUser%isolation%";"NewFirstName%isolation%";"NewLastName%isolation%";"NewEmail%isolation%@example.com";"123123qa";"123123qa";"-";"-";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
-"-";"-";"-";"-";"-";"-";"-";"1";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"
-"-";"-";"-";"-";"-";"-";"Inactive";"-";"1";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
+"initialUser/dataSet";"user/data/username";"user/data/firstname";"user/data/lastname";"user/data/email";"user/data/password";"user/data/password_confirmation";"user/data/is_active";"user/data/role_id/dataSet";"loginAsDefaultAdmin";"constraint"
+"custom_admin_with_default_role";"NewAdminUser%isolation%";"NewFirstName%isolation%";"NewLastName%isolation%";"NewEmail%isolation%@example.com";"123123qa";"123123qa";"-";"-";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
+"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"-";"role_sales";"0";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"
+"custom_admin_with_default_role";"-";"-";"-";"-";"-";"-";"Inactive";"-";"1";"assertUserSuccessSaveMessage, assertUserInGrid, assertUserSuccessLogOut, assertUserWrongCredentialsMessage"
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..e86507cf1e628f72a55d086eb8688093fbfe2b4f
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\User\Test\TestCase;
+
+use Magento\Backend\Test\Page\AdminAuthLogin;
+use Magento\Backend\Test\Page\Dashboard;
+use Magento\User\Test\Page\Adminhtml\UserRoleIndex;
+use Magento\User\Test\Page\Adminhtml\UserRoleEditRole;
+use Magento\User\Test\Fixture\User;
+use Magento\User\Test\Fixture\AdminUserRole;
+use Mtf\TestCase\Injectable;
+
+/**
+ * Test Creation for UpdateAdminUserRoleEntity
+ *
+ * Test Flow:
+ * Preconditions:
+ * 1. Create new admin user and assign it to new role.
+ * Steps:
+ * 1. Log in as admin user from data set.
+ * 2. Go to System>Permissions>User Roles
+ * 3. Open role created in precondition
+ * 4. Fill in data according to data set
+ * 5. Perform all assertions
+ *
+ * @group ACL_(PS)
+ * @ZephyrId MAGETWO-24768
+ */
+class UpdateAdminUserRoleEntityTest extends Injectable
+{
+    /**
+     * @var UserRoleIndex
+     */
+    protected $rolePage;
+
+    /**
+     * @var UserRoleEditRole
+     */
+    protected $userRoleEditRole;
+
+    /**
+     * @var AdminAuthLogin
+     */
+    protected $adminAuthLogin;
+
+    /**
+     * @var Dashboard
+     */
+    protected $dashboard;
+
+    /**
+     * Setup data for test
+     *
+     * @param UserRoleIndex $rolePage
+     * @param UserRoleEditRole $userRoleEditRole
+     * @param AdminAuthLogin $adminAuthLogin
+     * @param Dashboard $dashboard
+     * @return void
+     */
+    public function __inject(
+        UserRoleIndex $rolePage,
+        UserRoleEditRole $userRoleEditRole,
+        AdminAuthLogin $adminAuthLogin,
+        Dashboard $dashboard
+    ) {
+        $this->rolePage = $rolePage;
+        $this->userRoleEditRole = $userRoleEditRole;
+        $this->adminAuthLogin = $adminAuthLogin;
+        $this->dashboard = $dashboard;
+    }
+
+    /**
+     * Runs Update Admin User Roles Entity test
+     *
+     * @param AdminUserRole $roleInit
+     * @param AdminUserRole $role
+     * @param User $user
+     * @return array
+     */
+    public function testUpdateAdminUserRolesEntity(
+        AdminUserRole $roleInit,
+        AdminUserRole $role,
+        User $user
+    ) {
+        // Preconditions
+        $roleInit->persist();
+        if (!$user->hasData('user_id')) {
+            $user->persist();
+        }
+
+        // Steps
+        $filter = ['rolename' => $roleInit->getRoleName()];
+        $this->adminAuthLogin->open();
+        $this->adminAuthLogin->getLoginBlock()->fill($user);
+        $this->adminAuthLogin->getLoginBlock()->submit();
+        $this->rolePage->open();
+        $this->rolePage->getRoleGrid()->searchAndOpen($filter);
+        $this->userRoleEditRole->getRoleFormTabs()->fill($role);
+        $this->userRoleEditRole->getPageActions()->save();
+
+        return [
+            'customAdmin' => $role->hasData('in_role_users')
+                ? $role->getDataFieldConfig('in_role_users')['source']->getAdminUsers()[0]
+                : $user,
+        ];
+    }
+
+    /**
+     * Logout Admin User from account
+     *
+     * @return void
+     */
+    public function tearDown()
+    {
+        $this->dashboard->getAdminPanelHeader()->logOut();
+    }
+}
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv
new file mode 100644
index 0000000000000000000000000000000000000000..a90ad495b8a14e8a56b4e4d1e3d0e10bda85f0d9
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/User/Test/TestCase/UpdateAdminUserRoleEntityTest/testUpdateAdminUserRolesEntity.csv
@@ -0,0 +1,3 @@
+"user/dataSet";"role/data/rolename";"role/data/resource_access";"role/data/roles_resources";"role/data/in_role_users/dataSet";"constraint"
+"custom_admin_with_default_role";"NewAdminRole%isolation%";"-";"-";"-";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin"
+"default";"-";"Custom";"Sales";"custom_admin";"assertRoleSuccessSaveMessage, assertRoleInGrid, assertUserSuccessLogOut, assertUserSuccessLogin, assertUserRoleSalesRestrictedAccess"
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
index 75b2f2086ca678f7fe1dd2254e24b9f177a63248..035d48f03d22bece6d7d9c4b599945ce1a4a3af6 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/curl/di.xml
@@ -25,5 +25,5 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
     <preference for="Magento\User\Test\Handler\AdminUserRole\AdminUserRoleInterface" type="\Magento\User\Test\Handler\AdminUserRole\Curl"/>
-    <preference for="Magento\User\Test\Handler\AdminUser\AdminUserInterface" type="\Magento\User\Test\Handler\AdminUser\Curl"/>
+    <preference for="Magento\User\Test\Handler\User\UserInterface" type="\Magento\User\Test\Handler\User\Curl"/>
 </config>
\ No newline at end of file
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
index 447fa763412a6123c1a3cc39a0c70fd7347500f3..cff67adbe367d32e12b74d9c5891a3aebfbd6c2b 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/constraint.xml
@@ -29,8 +29,8 @@
         <require>
             <dashboard class="Magento\Backend\Test\Page\Dashboard" />
             <adminAuth class="Magento\Backend\Test\Page\AdminAuthLogin" />
-            <user class="Magento\User\Test\Fixture\AdminUserInjectable" />
-            <customAdmin class="Magento\User\Test\Fixture\AdminUserInjectable" />
+            <user class="Magento\User\Test\Fixture\User" />
+            <customAdmin class="Magento\User\Test\Fixture\User" />
         </require>
     </assertUserSuccessLogin>
     <assertUserSuccessLogOut module="Magento_User">
@@ -44,11 +44,15 @@
         <severeness>low</severeness>
         <require>
             <adminAuth class="Magento\Backend\Test\Page\AdminAuthLogin" />
-            <customAdmin class="Magento\User\Test\Fixture\AdminUserInjectable" />
+            <customAdmin class="Magento\User\Test\Fixture\User" />
         </require>
     </assertUserWrongCredentialsMessage>
     <assertUserRoleSalesRestrictedAccess module="Magento_User">
         <severeness>low</severeness>
+        <require>
+            <userIndex class="Magento\User\Test\Page\Adminhtml\UserIndex" />
+            <dashboard class="Magento\Backend\Test\Page\Dashboard" />
+        </require>
     </assertUserRoleSalesRestrictedAccess>
     <assertRoleSuccessSaveMessage module="Magento_User">
         <severeness>low</severeness>
@@ -66,8 +70,7 @@
         <severeness>low</severeness>
         <require>
             <userIndex class="Magento\User\Test\Page\Adminhtml\UserIndex" />
-            <user class="Magento\User\Test\Fixture\AdminUserInjectable" />
-            <customAdmin class="Magento\User\Test\Fixture\AdminUserInjectable" />
+            <user class="Magento\User\Test\Fixture\User" />
         </require>
     </assertUserInGrid>
     <assertUserSuccessSaveMessage module="Magento_User">
@@ -112,4 +115,17 @@
             <userIndex class="Magento\User\Test\Page\Adminhtml\UserIndex" />
         </require>
     </assertUserNotInGrid>
+    <assertUserDuplicateMessage module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <userEdit class="Magento\User\Test\Page\Adminhtml\UserEdit" />
+        </require>
+    </assertUserDuplicateMessage>
+    <assertUserInvalidEmailMessage module="Magento_User">
+        <severeness>low</severeness>
+        <require>
+            <userEdit class="Magento\User\Test\Page\Adminhtml\UserEdit" />
+            <user class="Magento\User\Test\Fixture\User" />
+        </require>
+    </assertUserInvalidEmailMessage>
 </constraint>
diff --git a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
index 097d3e5dd5e46235663351ffd7419d2ba199e281..b5ee11b7bb10def0bb6fd3a38fa8c38a730ca163 100644
--- a/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
+++ b/dev/tests/functional/tests/app/Magento/User/Test/etc/global/fixture.xml
@@ -24,11 +24,11 @@
  */
 -->
 <fixture>
-    <adminUserInjectable module="Magento_User">
+    <user module="Magento_User">
         <type>flat</type>
         <entity_type>admin_user</entity_type>
         <collection>Magento\User\Model\Resource\User\Collection</collection>
-    </adminUserInjectable>
+    </user>
     <adminUserRole module="Magento_User">
         <type>flat</type>
         <entity_type>admin_role</entity_type>
diff --git a/dev/tests/integration/testsuite/Magento/Backend/App/Router/DefaultRouterTest.php b/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
similarity index 85%
rename from dev/tests/integration/testsuite/Magento/Backend/App/Router/DefaultRouterTest.php
rename to dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
index 70d0c0aa34e825e9b7d18a63166c905d7ab2be0f..d5d2119647909fb0b08379e678511b291efc68c0 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/App/Router/DefaultRouterTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/App/RouterTest.php
@@ -21,15 +21,15 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\App\Router;
+namespace Magento\Backend\App;
 
 /**
  * @magentoAppArea adminhtml
  */
-class DefaultRouterTest extends \PHPUnit_Framework_TestCase
+class RouterTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Backend\App\Router\DefaultRouter
+     * @var \Magento\Backend\App\Router
      */
     protected $model;
 
@@ -41,7 +41,7 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
     protected function setUp()
     {
         $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $this->model = $this->objectManager->create('Magento\Backend\App\Router\DefaultRouter');
+        $this->model = $this->objectManager->create('Magento\Backend\App\Router');
     }
 
     public function testRouterCanProcessRequestsWithProperPathInfo()
@@ -61,20 +61,16 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetControllerClassName($module, $controller, $className)
     {
-        $this->assertEquals($className, $this->model->getControllerClassName($module, $controller));
+        $this->assertEquals($className, $this->model->getActionClassName($module, $controller));
     }
 
     public function getControllerClassNameDataProvider()
     {
         return array(
             array('Magento_Index', 'process', 'Magento\Index\Controller\Adminhtml\Process'),
-            array('Magento_Index_Adminhtml', 'process', 'Magento\Index\Controller\Adminhtml\Process')
         );
     }
 
-    /**
-     * @magentoDataFixture Magento/TestFixture/Controller/Adminhtml/Index.php
-     */
     public function testMatchCustomNoRouteAction()
     {
         if (!\Magento\TestFramework\Helper\Bootstrap::canTestHeaders()) {
@@ -85,7 +81,7 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
             'testmodule' => array(
                 'frontName' => 'testfixture',
                 'id' => 'testfixture',
-                'modules' => array('Magento_TestFixture_Adminhtml')
+                'modules' => array('Magento_TestFixture')
             )
         );
 
@@ -104,7 +100,7 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
         $routeConfig->expects($this->any())->method('_getRoutes')->will($this->returnValue($routers));
 
         $defaultRouter = $this->objectManager->create(
-            'Magento\Backend\App\Router\DefaultRouter',
+            'Magento\Backend\App\Router',
             array('routeConfig' => $routeConfig)
         );
 
@@ -113,7 +109,7 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
 
         $request->setPathInfo('backend/testfixture/test_controller');
         $controller = $defaultRouter->match($request);
-        $this->assertInstanceOf('Magento\TestFixture\Controller\Adminhtml\Index', $controller);
+        $this->assertInstanceOf('Magento\TestFixture\Controller\Adminhtml\Noroute', $controller);
         $this->assertEquals('noroute', $request->getActionName());
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php
index ad5dc60fee109a29c26aac81f3df0692d283d0c5..fa773d7b14f5e5811d24e27f361784a849cce0e3 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Category/EditTest.php
@@ -36,13 +36,14 @@ class EditTest extends \PHPUnit_Framework_TestCase
      *
      * @param array $blockAttributes
      * @param array $expected
+     *
+     * @magentoAppIsolation enabled
      */
     public function testPrepareLayout($blockAttributes, $expected)
     {
         /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout',
-            array('area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
 
         /** @var $block \Magento\Backend\Block\Urlrewrite\Catalog\Category\Edit */
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php
index f62a3c65f9f0411b8d710c1dd956fea84ec30951..e458d8bc2aeea1e95b228a5367a809f5f83489f4 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Catalog/Product/EditTest.php
@@ -36,13 +36,14 @@ class EditTest extends \PHPUnit_Framework_TestCase
      *
      * @param array $blockAttributes
      * @param array $expected
+     *
+     * @magentoAppIsolation enabled
      */
     public function testPrepareLayout($blockAttributes, $expected)
     {
         /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout',
-            array('area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
 
         /** @var $block \Magento\Backend\Block\Urlrewrite\Catalog\Product\Edit */
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php
index 79d9cffe9ce7bfae22d199d2e37ed90d22b88661..91ad9c95ba11ced75de730af7b28ce895958c52e 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/Cms/Page/EditTest.php
@@ -36,13 +36,14 @@ class EditTest extends \PHPUnit_Framework_TestCase
      *
      * @param array $blockAttributes
      * @param array $expected
+     *
+     * @magentoAppIsolation enabled
      */
     public function testPrepareLayout($blockAttributes, $expected)
     {
         /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout',
-            array('area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
 
         /** @var $block \Magento\Backend\Block\Urlrewrite\Cms\Page\Edit */
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php
index 640a9b528e00df1e182325f1c7121fcdf95ad04d..20ab0578ec23bb3d8c3ec63a89987e535ac245f8 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Urlrewrite/EditTest.php
@@ -36,14 +36,15 @@ class EditTest extends \PHPUnit_Framework_TestCase
      *
      * @param array $blockAttributes
      * @param array $expected
+     *
+     * @magentoAppIsolation enabled
      */
     public function testPrepareLayout($blockAttributes, $expected)
     {
 
         /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout',
-            array('area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
 
         /** @var $block \Magento\Backend\Block\Urlrewrite\Edit */
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/ContainerTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/ContainerTest.php
index b55204a83f011e48e2c5760030e462c43fd11a7a..89cf883cbac670bcd71179c1352c36164d03e3e3 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/ContainerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/ContainerTest.php
@@ -28,6 +28,9 @@ namespace Magento\Backend\Block\Widget;
  */
 class ContainerTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testPseudoConstruct()
     {
         /** @var $block \Magento\Backend\Block\Widget\Container */
@@ -47,6 +50,9 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         $this->assertContains('two', $block->getHeaderText());
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testGetButtonsHtml()
     {
         $titles = array(1 => 'Title 1', 'Title 2', 'Title 3');
@@ -59,19 +65,15 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         }
     }
 
+    /**
+     * @magentoAppIsolation enabled
+     */
     public function testUpdateButton()
     {
         $originalTitles = array(1 => 'Title 1', 'Title 2', 'Title 3');
         $newTitles = array(1 => 'Button A', 'Button B', 'Button C');
 
         $block = $this->_buildBlock($originalTitles);
-        $html = $block->getButtonsHtml('header');
-        foreach ($newTitles as $newTitle) {
-            $this->assertNotContains($newTitle, $html);
-        }
-
-        $block = $this->_buildBlock($originalTitles);
-        // Layout caches html, thus recreate block for further testing
         foreach ($newTitles as $id => $newTitle) {
             $block->updateButton($id, 'title', $newTitle);
         }
@@ -85,17 +87,17 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
      * Composes a container with several buttons in it
      *
      * @param array $titles
+     * @param string $blockName
      * @return \Magento\Backend\Block\Widget\Container
      */
-    protected function _buildBlock($titles)
+    protected function _buildBlock($titles, $blockName = 'block')
     {
         /** @var $layout \Magento\Framework\View\LayoutInterface */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout',
-            array('area' => \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE)
+        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
         /** @var $block \Magento\Backend\Block\Widget\Container */
-        $block = $layout->createBlock('Magento\Backend\Block\Widget\Container', 'block');
+        $block = $layout->createBlock('Magento\Backend\Block\Widget\Container', $blockName);
         foreach ($titles as $id => $title) {
             $block->addButton($id, array('title' => $title), 0, 0, 'header');
         }
diff --git a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
index 7bbebb6c543af104df72911b350bc5e87141fe9c..10942a6097d699542e3aaa6b3e418083088fe8e8 100644
--- a/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
+++ b/dev/tests/integration/testsuite/Magento/Backend/Block/Widget/Form/ContainerTest.php
@@ -40,7 +40,7 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
         $block = $this->getMock(
             'Magento\Backend\Block\Widget\Form\Container',
             array('_prepareLayout'),
-            array($objectManager->create('Magento\Backend\Block\Template\Context'))
+            array($objectManager->create('Magento\Backend\Block\Widget\Context'))
         );
 
         $layout->addBlock($block, 'block');
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/JsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/JsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f839d1d1ecfffc5c7591a5ec55b526ca66fa4298
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Block/Adminhtml/Product/Edit/JsTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Catalog\Block\Adminhtml\Product\Edit;
+
+/**
+ * @magentoAppArea adminhtml
+ */
+class JsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testGetAllRatesByProductClassJson()
+    {
+        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var \Magento\Tax\Model\Calculation\Rule $fixtureTaxRule */
+        $fixtureTaxRule = $objectManager->create('Magento\Tax\Model\Calculation\Rule');
+        $fixtureTaxRule->load('Test Rule', 'code');
+        $defaultCustomerTaxClass = 3;
+        $fixtureTaxRule
+            ->setTaxCustomerClass(array_merge($fixtureTaxRule->getCustomerTaxClasses(), [$defaultCustomerTaxClass]))
+            ->setTaxProductClass($fixtureTaxRule->getProductTaxClasses())
+            ->setTaxRate($fixtureTaxRule->getRates())
+            ->saveCalculationData();
+        /** @var \Magento\Catalog\Block\Adminhtml\Product\Edit\Js $block */
+        $block = $objectManager->create('Magento\Catalog\Block\Adminhtml\Product\Edit\Js');
+        $jsonResult = $block->getAllRatesByProductClassJson();
+        $decodedResult = json_decode($jsonResult);
+        $this->assertNotEmpty($decodedResult, 'Resulting JSON is invalid.');
+        $taxClassesArray = (array)$decodedResult;
+        $defaultProductTaxClass = 2;
+        $expectedProductTaxClasses = array_unique(
+            array_merge($fixtureTaxRule->getProductTaxClasses(), [$defaultProductTaxClass])
+        );
+        $this->assertCount(
+            count($expectedProductTaxClasses),
+            $taxClassesArray,
+            'Invalid quantity of rates for tax classes.'
+        );
+        foreach ($expectedProductTaxClasses as $taxClassId) {
+            $this->assertArrayHasKey(
+                "value_{$taxClassId}",
+                $taxClassesArray,
+                "Rates for tax class with ID '{$taxClassId}' is missing."
+            );
+        }
+        $this->assertContains('7.5', $jsonResult, 'Rates for tax classes looks to be invalid.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/PriceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/PriceTest.php
deleted file mode 100644
index 944b4be6795231634f745619539ac56d0a44c786..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Catalog/Helper/Product/PriceTest.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-
-namespace Magento\Catalog\Helper\Product;
-
-use Magento\Customer\Service\V1\CustomerGroupServiceInterface;
-use Magento\TestFramework\Helper\Bootstrap;
-
-/**
- * Test class for Magento\Catalog\Helper\Product\Price
- */
-class PriceTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Catalog\Helper\Product\Price
-     */
-    protected $_helper;
-
-    /**
-     * @var CustomerGroupServiceInterface CustomerAccountServiceInterface
-     */
-    protected $_customerAccountService;
-
-    protected function setUp()
-    {
-        $this->_helper = Bootstrap::getObjectManager()->get('Magento\Catalog\Helper\Product\Price');
-        $this->_customerAccountService = Bootstrap::getObjectManager()->get(
-            'Magento\Customer\Service\V1\CustomerAccountServiceInterface'
-        );
-
-    }
-
-    /**
-     * @magentoDataFixture Magento/Customer/_files/customer.php
-     */
-    public function testSetCustomer()
-    {
-        $customerData = $this->_customerAccountService->getCustomer(1);
-        $this->assertInstanceOf('Magento\Catalog\Helper\Product\Price', $this->_helper->setCustomer($customerData));
-        $customerDataRetrieved = $this->_helper->getCustomer();
-        $this->assertEquals($customerData->__toArray(), $customerDataRetrieved->__toArray());
-    }
-
-}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..50744fa64cbf7398581e1b1ea34855fa815a5c85
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Full reindex Test
+ */
+class FullTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_processor;
+
+    protected function setUp()
+    {
+        $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Catalog\Model\Indexer\Product\Eav\Processor'
+        );
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testReindexAll()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attr **/
+        $attr = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config')
+            ->getAttribute('catalog_product', 'weight');
+        $attr->setIsFilterable(1)->save();
+
+        $this->assertTrue($attr->isIndexable());
+
+        $this->_processor->reindexAll();
+
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->addAttributeToSelect('weight');
+
+        $this->assertCount(1, $productCollection);
+
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(1, $product->getWeight());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bc05c66ecbcc6626f58acbf2009567e8890b87cc
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Row reindex Test
+ */
+class RowTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testUpdateProduct()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attr **/
+        $attr = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config')
+            ->getAttribute('catalog_product', 'weight');
+        $attr->setIsFilterable(1)->save();
+
+        $this->assertTrue($attr->isIndexable());
+
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Catalog\Model\Product'
+        );
+
+        $product->load(1);
+        $product->setWeight(11);
+        $product->save();
+
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->addAttributeToSelect('weight');
+
+        $this->assertCount(1, $productCollection);
+
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(11, $product->getWeight());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..73fd801b8bd9f0daa85d364054ef4fda05e20307
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+/**
+ * Rows reindex Test
+ */
+class RowsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Product\Action
+     */
+    protected $_productAction;
+
+    protected function setUp()
+    {
+        $this->_productAction = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Catalog\Model\Product\Action'
+        );
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testUpdateAttributes()
+    {
+        /** @var \Magento\Catalog\Model\Resource\Eav\Attribute $attr **/
+        $attr = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Eav\Model\Config')
+            ->getAttribute('catalog_product', 'weight');
+        $attr->setIsFilterable(1)->save();
+
+        $this->assertTrue($attr->isIndexable());
+
+        $this->_productAction->updateAttributes(
+            array(1),
+            array('weight' => 11),
+            1
+        );
+
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->addAttributeToSelect('weight');
+
+        $this->assertCount(1, $productCollection);
+
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(11, $product->getWeight());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
index 7f95890098d6120ae0492ac2550216c788cc7758..552c9afad59b9f0390d29e0e8e655f31a8916464 100644
--- a/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Catalog/Model/Resource/Product/Indexer/Eav/SourceTest.php
@@ -37,6 +37,11 @@ class SourceTest extends \PHPUnit_Framework_TestCase
      */
     protected $productResource;
 
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_eavIndexerProcessor;
+
     /**
      * Sets up the fixture, for example, opens a network connection.
      * This method is called before a test is executed.
@@ -47,10 +52,13 @@ class SourceTest extends \PHPUnit_Framework_TestCase
             'Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source'
         );
 
-        /** @var \Magento\Catalog\Model\Resource\Product $productResource */
         $this->productResource = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
             'Magento\Catalog\Model\Resource\Product'
         );
+
+        $this->_eavIndexerProcessor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Catalog\Model\Indexer\Product\Eav\Processor'
+        );
     }
 
     /**
@@ -63,6 +71,8 @@ class SourceTest extends \PHPUnit_Framework_TestCase
            ->getAttribute('catalog_product', 'test_configurable');
         $attr->setIsFilterable(1)->save();
 
+        $this->_eavIndexerProcessor->reindexAll();
+
         /** @var \Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection $options **/
         $options = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
             'Magento\Eav\Model\Resource\Entity\Attribute\Option\Collection'
diff --git a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
index abb620ebd156cffd3991a709e6d8c0f192bf82d1..230b0a757491e548ea1c95cf6d0368c3a72f6356 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/AbstractTest.php
@@ -92,7 +92,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'name' => 'Simple Product 3',
                     'price' => 150,
                     'status' => 1,
-                    'tax_class_id' => '0',
+                    'tax_class_id' => '2',
                     'weight' => 1,
                     'description' => 'a',
                     'short_description' => 'a',
@@ -103,7 +103,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'name' => 'Simple Product 3',
                     'price' => 150,
                     'status' => 1,
-                    'tax_class_id' => '0',
+                    'tax_class_id' => '2',
                     'weight' => 1,
                     'description' => 'a',
                     'short_description' => 'a',
@@ -124,7 +124,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'name' => 'Simple Product 4',
                     'price' => 100,
                     'status' => 1,
-                    'tax_class_id' => '0',
+                    'tax_class_id' => '2',
                     'weight' => 1,
                     'description' => 'a',
                     'short_description' => 'a',
@@ -137,7 +137,7 @@ class AbstractTest extends \PHPUnit_Framework_TestCase
                     'name' => 'Simple Product 4',
                     'price' => 100,
                     'status' => 1,
-                    'tax_class_id' => '0',
+                    'tax_class_id' => '2',
                     'weight' => 1,
                     'description' => 'a',
                     'short_description' => 'a',
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
index 6ffc20b9755d6c380b88a52343c2d042e2cfee5a..a41797d66e52fb093ad823baa19a9dcf00b40698 100644
--- a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Config/Backend/ManagestockTest.php
@@ -74,6 +74,7 @@ class ManagestockTest extends \PHPUnit_Framework_TestCase
             Bootstrap::getObjectManager()->get('\Magento\Framework\Registry'),
             Bootstrap::getObjectManager()->get('\Magento\Framework\App\Config\ScopeConfigInterface'),
             $stockStatus,
+            Bootstrap::getObjectManager()->get('Magento\CatalogInventory\Model\Indexer\Stock\Processor'),
             Bootstrap::getObjectManager()->get('Magento\Core\Model\Resource\Config')
         );
 
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..433c453e4fa21a3c2aceaf960823f7b76ab48637
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Full reindex Test
+ */
+class FullTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_processor;
+
+    protected function setUp()
+    {
+        $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\CatalogInventory\Model\Indexer\Stock\Processor'
+        );
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testReindexAll()
+    {
+        $this->_processor->reindexAll();
+
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->joinField(
+            'qty',
+            'cataloginventory_stock_status_idx',
+            'qty',
+            'product_id=entity_id',
+            '{{table}}.stock_id=1',
+            'left'
+        );
+
+        $this->assertCount(1, $productCollection);
+
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(100, $product->getQty());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..448a031dac11f350c0124ca49655309930313a44
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Class RowTest
+ */
+class RowTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_processor;
+
+    protected function setUp()
+    {
+        $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\CatalogInventory\Model\Indexer\Stock\Processor'
+        );
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testProductUpdate()
+    {
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */
+        $stockItem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\CatalogInventory\Model\Stock\Item'
+        );
+
+        $this->_processor->getIndexer()->setScheduled(false);
+        $this->assertFalse($this->_processor->getIndexer()->isScheduled());
+
+        $stockItem->loadByProduct(1);
+        $stockItem->addQty(11);
+        $stockItem->save();
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->joinField(
+            'qty',
+            'cataloginventory_stock_status',
+            'qty',
+            'product_id=entity_id',
+            '{{table}}.stock_id=1',
+            'left'
+        );
+
+        $this->assertEquals(1, $productCollection->count());
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(111, $product->getQty());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..186e2bb4558ef79255a6064e8b7a725aaee7f383
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+/**
+ * Class RowsTest
+ */
+class RowsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor
+     */
+    protected $_processor;
+
+    protected function setUp()
+    {
+        $this->_processor = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\CatalogInventory\Model\Indexer\Stock\Processor'
+        );
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Catalog/_files/product_simple.php
+     */
+    public function testProductUpdate()
+    {
+        $categoryFactory = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\Catalog\Model\CategoryFactory'
+        );
+        /** @var \Magento\Catalog\Block\Product\ListProduct $listProduct */
+        $listProduct = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\Catalog\Block\Product\ListProduct'
+        );
+
+        /** @var \Magento\CatalogInventory\Model\Stock\Item $stockItem */
+        $stockItem = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            '\Magento\CatalogInventory\Model\Stock\Item'
+        );
+
+        $stockItem->loadByProduct(1);
+        $stockItem->setProcessIndexEvents(false);
+        $stockItem->addQty(11);
+        $stockItem->save();
+
+        $this->_processor->reindexList(array(1));
+
+        $category = $categoryFactory->create()->load(2);
+        $layer = $listProduct->getLayer();
+        $layer->setCurrentCategory($category);
+        $productCollection = $layer->getProductCollection();
+        $productCollection->joinField(
+            'qty',
+            'cataloginventory_stock_status',
+            'qty',
+            'product_id=entity_id',
+            '{{table}}.stock_id=1',
+            'left'
+        );
+
+        $this->assertEquals(1, $productCollection->count());
+        /** @var $product \Magento\Catalog\Model\Product */
+        foreach ($productCollection as $product) {
+            $this->assertEquals('Simple Product', $product->getName());
+            $this->assertEquals('Short description', $product->getShortDescription());
+            $this->assertEquals(111, $product->getQty());
+        }
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
index fc47ecf943eb3b11a5ea6afef51d51255a17db60..98c6a3e760e05f543a4259d4981bf133901dca3f 100644
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
+++ b/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
@@ -81,7 +81,7 @@ class OnepageTest extends \Magento\TestFramework\TestCase\AbstractController
 
     public function testShippingMethodAction()
     {
-        $this->dispatch('checkout/onepage/shippingmethod');
+        $this->dispatch('checkout/onepage/shippingMethod');
         $this->assertContains('no quotes are available', $this->getResponse()->getBody());
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Core/App/Router/BaseTest.php b/dev/tests/integration/testsuite/Magento/Core/App/Router/BaseTest.php
index 8261bf0df6c9ff60bf4872f13e61ddfa69c89611..2be020472338d7b38cfdf565748609ae2db7ee53 100644
--- a/dev/tests/integration/testsuite/Magento/Core/App/Router/BaseTest.php
+++ b/dev/tests/integration/testsuite/Magento/Core/App/Router/BaseTest.php
@@ -73,7 +73,7 @@ class BaseTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertEquals(
             'Magento\Core\Controller\Index',
-            $this->_model->getControllerClassName('Magento_Core', 'index')
+            $this->_model->getActionClassName('Magento_Core', 'index')
         );
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Core/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Core/Controller/IndexTest.php
index 1dbc1ca9e0a8dd0db1c0f767bc044cb042e75893..a8141251ba401faccc9795573d1f2a94d4dee68a 100644
--- a/dev/tests/integration/testsuite/Magento/Core/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Core/Controller/IndexTest.php
@@ -27,7 +27,7 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
 {
     public function testNotFoundAction()
     {
-        $this->dispatch('core/index/notfound');
+        $this->dispatch('core/index/notFound');
         $this->assertEquals('404', $this->getResponse()->getHttpResponseCode());
         $this->assertEquals('Requested resource not found', $this->getResponse()->getBody());
     }
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
index 73e60223e169a05e58e1f6f81a592da3e3b0fa71..e0cb2e0215eea91613cd685b0a7dded20fe17933 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/Edit/FormTest.php
@@ -24,11 +24,8 @@
 
 namespace Magento\Customer\Block\Adminhtml\Group\Edit;
 
-use Magento\Backend\App\Area\FrontNameResolver;
 use Magento\Customer\Controller\RegistryConstants;
 use Magento\Customer\Service\V1\Data\CustomerGroup;
-use Magento\Framework\Service\V1\Data\FilterBuilder;
-use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
 use Magento\TestFramework\Helper\Bootstrap;
 
 /**
@@ -99,6 +96,9 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $this->assertNotNull($idElement);
         $this->assertEquals('1', $idElement->getValue());
         $this->assertEquals('3', $taxClassIdElement->getValue());
+        /** @var \Magento\Tax\Model\TaxClass\Source\Customer $taxClassCustomer */
+        $taxClassCustomer = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
+        $this->assertEquals($taxClassCustomer->toOptionArray(false), $taxClassIdElement->getData('values'));
         $this->assertEquals('General', $groupCodeElement->getValue());
     }
 
@@ -107,7 +107,7 @@ class FormTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetFormExistInCustomGroup()
     {
-        $builder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
+        $builder = Bootstrap::getObjectManager()->create('Magento\Framework\Service\V1\Data\FilterBuilder');
         /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteria */
         $searchCriteria = Bootstrap::getObjectManager()
             ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder')
@@ -132,6 +132,9 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $this->assertNotNull($idElement);
         $this->assertEquals($customerGroup->getId(), $idElement->getValue());
         $this->assertEquals($customerGroup->getTaxClassId(), $taxClassIdElement->getValue());
+        /** @var \Magento\Tax\Model\TaxClass\Source\Customer $taxClassCustomer */
+        $taxClassCustomer = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
+        $this->assertEquals($taxClassCustomer->toOptionArray(false), $taxClassIdElement->getData('values'));
         $this->assertEquals($customerGroup->getCode(), $groupCodeElement->getValue());
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
index 0a44b35075f928e199e5bfa8bcb0322f713c56fd..f8a0492c937d879fe44f297b937c2f32479e628b 100644
--- a/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Block/Adminhtml/Group/EditTest.php
@@ -60,8 +60,8 @@ class EditTest extends AbstractController
     public function setUp()
     {
         parent::setUp();
-        $this->layout = Bootstrap::getObjectManager()->create(
-            'Magento\Framework\View\Layout'
+        $this->layout = Bootstrap::getObjectManager()->get(
+            'Magento\Framework\View\LayoutInterface'
         );
         $this->customerGroupService = Bootstrap::getObjectManager()
             ->create('Magento\Customer\Service\V1\CustomerGroupService');
@@ -78,6 +78,7 @@ class EditTest extends AbstractController
 
     /**
      * Verify that the Delete button does not exist for the default group.
+     * @magentoAppIsolation enabled
      */
     public function testDeleteButtonNotExistInDefaultGroup()
     {
diff --git a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
index bc10aaffba4bea8672d2438b128d0c28e46decde..4df8fdb2486a8b0944ae22b62c93245e51463dc7 100755
--- a/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
+++ b/dev/tests/integration/testsuite/Magento/Customer/Controller/AccountTest.php
@@ -96,7 +96,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController
         $this->getRequest()->setParam('token', $token);
         $this->getRequest()->setParam('id', $customer->getId());
 
-        $this->dispatch('customer/account/createpassword');
+        $this->dispatch('customer/account/createPassword');
         $text = $this->getResponse()->getBody();
         $this->assertTrue((bool)preg_match('/' . $token . '/m', $text));
     }
@@ -117,7 +117,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController
         $this->getRequest()->setParam('token', 'INVALIDTOKEN');
         $this->getRequest()->setParam('id', $customer->getId());
 
-        $this->dispatch('customer/account/createpassword');
+        $this->dispatch('customer/account/createPassword');
 
         // should be redirected to forgotpassword page
         $response = $this->getResponse();
@@ -259,7 +259,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController
     /**
      * @magentoDataFixture Magento/Customer/_files/customer.php
      */
-    public function testOpenActionCreatepasswordAction()
+    public function testOpenActionCreatePasswordAction()
     {
         /** @var \Magento\Customer\Model\Customer $customer */
         $customer = Bootstrap::getObjectManager()
@@ -272,7 +272,7 @@ class AccountTest extends \Magento\TestFramework\TestCase\AbstractController
         $this->getRequest()->setParam('token', $token);
         $this->getRequest()->setParam('id', $customer->getId());
 
-        $this->dispatch('customer/account/createpassword');
+        $this->dispatch('customer/account/createPassword');
         $this->assertNotEmpty($this->getResponse()->getBody());
 
         $headers = $this->getResponse()->getHeaders();
diff --git a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php
index e30bec53b2e58dcb97a22b63d75a03bb0da188c0..8d5ec89b9461358ee3776feb4dca0778acdebb40 100644
--- a/dev/tests/integration/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php
+++ b/dev/tests/integration/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php
@@ -113,7 +113,7 @@ class AgreementTest extends \Magento\TestFramework\TestCase\AbstractController
         );
         /** @var \Magento\Paypal\Controller\Billing\Agreement $billingAgreementController */
         $billingAgreementController = $objectManager->create(
-            'Magento\Paypal\Controller\Billing\Agreement',
+            'Magento\Paypal\Controller\Billing\Agreement\ReturnWizard',
             ['context' => $contextMock]
         );
 
@@ -124,7 +124,7 @@ class AgreementTest extends \Magento\TestFramework\TestCase\AbstractController
         $customerSession->setCustomerId($fixtureCustomerId);
 
         /** Execute SUT */
-        $billingAgreementController->returnWizardAction();
+        $billingAgreementController->execute();
 
         /** Ensure that billing agreement record was created in the DB */
         /** @var \Magento\Paypal\Model\Resource\Billing\Agreement\Collection $billingAgreementCollection */
diff --git a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
index 0032e2cad6f141b15faf52c9a3dc2190c3b1a44d..53d0573346a934b6d7b8ec6f16446be8c28096d1 100644
--- a/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreateTest.php
@@ -205,7 +205,7 @@ class CreateTest extends \Magento\Backend\Utility\Controller
             ->loadArea('adminhtml');
 
         $this->dispatch('backend/sales/order_create/save');
-        $this->assertEquals('denied', $this->getRequest()->getActionName());
+        $this->assertEquals('403', $this->getResponse()->getHttpResponseCode());
     }
 }
 
@@ -220,6 +220,6 @@ class AuthorizationMock extends \Magento\Framework\Authorization
      */
     public function isAllowed($resource, $privilege = null)
     {
-        return $resource == 'Magento_Customer::manage' ? false : parent::isAllowed($resource, $privilege);
+        return $resource == 'Magento_Sales::create' ? false : parent::isAllowed($resource, $privilege);
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Store/_files/store.php b/dev/tests/integration/testsuite/Magento/Store/_files/store.php
new file mode 100644
index 0000000000000000000000000000000000000000..46eb7f7f119605edb8ea7c381a89f27ccacc8064
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Store/_files/store.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/** @var $store \Magento\Store\Model\Store */
+$store = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Store\Model\Store');
+$store->setData(
+    array(
+        'code' => 'test',
+        'website_id' => '1',
+        'group_id' => '1',
+        'name' => 'Test Store',
+        'sort_order' => '0',
+        'is_active' => '1'
+    )
+);
+$store->save();
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/FormTest.php b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ae6719b1fea296cba8ad18bc25fe927daf5f8d2
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/FormTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Block\Adminhtml\Rate;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $_objectManager;
+
+    /** @var \Magento\Tax\Block\Adminhtml\Rate\Form */
+    protected $_block;
+
+    protected function setUp()
+    {
+        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->_block = $this->_objectManager->create(
+            'Magento\Tax\Block\Adminhtml\Rate\Form'
+        );
+    }
+
+    public function testGetRateCollection()
+    {
+        /** @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\Calculation\Rate\Collection');
+        $dbTaxRatesQty = $collection->count();
+        if (($dbTaxRatesQty == 0) || ($collection->getFirstItem()->getId() != 1)) {
+            $this->fail("Preconditions failed.");
+        }
+
+        $ratesCollection = $this->_block->getRateCollection();
+
+        $collectionTaxRatesQty = count($ratesCollection);
+        $this->assertEquals($dbTaxRatesQty, $collectionTaxRatesQty, 'Tax rates quantity is invalid.');
+        $taxRate = $ratesCollection[0];
+        $expectedTaxRateData = [
+            'tax_calculation_rate_id' => '1',
+            'code' => 'US-CA-*-Rate 1',
+            'tax_country_id' => 'US',
+            'tax_region_id' => '12',
+            'region_name' => 'CA',
+            'tax_postcode' => '*',
+            'rate' => '8.25',
+            'zip_is_range' => null,
+            'zip_from' => null,
+            'zip_to' => null,
+            'rate' => '8.25',
+        ];
+        $this->assertEquals($taxRate, $expectedTaxRateData, 'Tax rate data is invalid.');
+    }
+
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/TitleTest.php b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/TitleTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a53cabe2c4c1c5050c86e418968d999c7f199c97
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rate/TitleTest.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Block\Adminhtml\Rate;
+
+use Magento\Tax\Model\Calculation\Rate;
+use Magento\Tax\Controller\RegistryConstants;
+
+class TitleTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Tax\Block\Adminhtml\Rate\Title
+     */
+    protected $_block;
+
+    /**
+     * @var \Magento\TestFramework\ObjectManager
+     */
+    protected $_objectManager;
+
+    protected function setUp()
+    {
+        /** @var $objectManager \Magento\TestFramework\ObjectManager */
+        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+    }
+
+    /**
+     * @magentoDataFixture Magento/Store/_files/store.php
+     * @magentoDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testGetTitles()
+    {
+        /** @var \Magento\Tax\Model\Calculation\Rate $rate */
+        $rate = $this->_objectManager->create('Magento\Tax\Model\Calculation\Rate');
+        $rate->load(1);
+        /** @var \Magento\Store\Model\Store $store */
+        $store = $this->_objectManager->get('Magento\Store\Model\Store');
+        $store->load('test', 'code');
+        $title = 'title';
+        $rate->saveTitles([$store->getId() => $title]);
+
+        $coreRegistry = $this->_objectManager->create('Magento\Framework\Registry');
+        $coreRegistry->register(RegistryConstants::CURRENT_TAX_RATE_ID, 1);
+
+        /** @var \Magento\Tax\Block\Adminhtml\Rate\Title $block */
+        $block = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Tax\Block\Adminhtml\Rate\Title',
+            [
+                'coreRegistry' => $coreRegistry,
+            ]
+        );
+        $titles = $block->getTitles();
+        $this->assertArrayHasKey($store->getId(), $titles, 'Store was not created');
+        $this->assertEquals($title, $titles[$store->getId()], 'Invalid Tax Title');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rule/Edit/FormTest.php b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rule/Edit/FormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..dfe84657d0f1ec7d9a6fd4bcf4b803da270418a5
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Block/Adminhtml/Rule/Edit/FormTest.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Block\Adminhtml\Rule\Edit;
+
+class FormTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\ObjectManager
+     */
+    protected $_objectManager;
+
+    /** @var \Magento\Tax\Block\Adminhtml\Rule\Edit\Form */
+    protected $_block;
+
+    protected function setUp()
+    {
+        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $customerTaxClassSourceMock = $this->getMockBuilder('Magento\Tax\Model\TaxClass\Source\Customer')
+            ->setMethods(['getAllOptions'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $customerTaxClassSourceMock->expects($this->any())
+            ->method('getAllOptions')
+            ->will(
+                $this->returnValue(
+                    [['value' => '1', 'name' => 'Retail Customer'], ['value' => '2', 'name' => 'Guest']]
+                )
+            );
+        $productTaxClassSourceMock = $this->getMockBuilder('Magento\Tax\Model\TaxClass\Source\Product')
+            ->setMethods(['getAllOptions'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $productTaxClassSourceMock->expects($this->any())
+            ->method('getAllOptions')
+            ->will(
+                $this->returnValue(
+                    [['value' => '1', 'name' => 'Taxable Goods'], ['value' => '2', 'name' => 'Shipping']]
+                )
+            );
+        $this->_block = $this->_objectManager->create(
+            'Magento\Tax\Block\Adminhtml\Rule\Edit\Form',
+            [
+                'registry' => $this->_objectManager->get('Magento\Framework\Registry'),
+                'customerTaxClassSource' => $customerTaxClassSourceMock,
+                'productTaxClassSource' => $productTaxClassSourceMock
+            ]
+        );
+    }
+
+    /**
+     * Test that first value in multiselect applied as default if there is no default value in config
+     *
+     * @magentoConfigFixture default_store tax/classes/default_customer_tax_class 0
+     */
+    public function testGetCustomerTaxClassWithDefaultFirstValue()
+    {
+        $this->assertEquals(1, $this->_block->getDefaultCustomerTaxClass());
+    }
+
+    /**
+     * Test that default value for multiselect is retrieve from config
+     *
+     * @magentoConfigFixture default_store tax/classes/default_customer_tax_class 2
+     */
+    public function testGetCustomerTaxClassWithDefaultFromConfig()
+    {
+        $this->assertEquals(2, $this->_block->getDefaultCustomerTaxClass());
+    }
+
+    /**
+     * Test that first value in multiselect applied as default if there is no default value in config
+     *
+     * @magentoConfigFixture default_store tax/classes/default_product_tax_class 0
+     */
+    public function testGetProductTaxClassWithDefaultFirstValue()
+    {
+        $this->assertEquals(1, $this->_block->getDefaultProductTaxClass());
+    }
+
+    /**
+     * Test that default value for multiselect is retrieve from config
+     *
+     * @magentoConfigFixture default_store tax/classes/default_product_tax_class 2
+     */
+    public function testGetProductTaxClassWithDefaultFromConfig()
+    {
+        $this->assertEquals(2, $this->_block->getDefaultProductTaxClass());
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
index b90e38871547cbd0a40b5fcfb69b8afa36b2bc1a..72eeca4c82989b678e0d987de13fad6dc9cc4b88 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/RateTest.php
@@ -30,6 +30,7 @@ class RateTest extends \Magento\Backend\Utility\Controller
 {
     /**
      * @dataProvider ajaxSaveActionDataProvider
+     * @magentoDbIsolation enabled
      */
     public function testAjaxSaveAction($postData, $expectedData)
     {
@@ -92,6 +93,7 @@ class RateTest extends \Magento\Backend\Utility\Controller
      * Test wrong data conditions
      *
      * @dataProvider ajaxSaveActionDataInvalidDataProvider
+     * @magentoDbIsolation enabled
      */
     public function testAjaxSaveActionInvalidData($postData, $expectedData)
     {
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/TaxTest.php b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/TaxTest.php
index 44394ed2ce5299ba6111845f7c475a007bc16b05..92435123b867121aa4b5499441b80e725ea1bd3c 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/TaxTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Controller/Adminhtml/TaxTest.php
@@ -23,13 +23,15 @@
  */
 namespace Magento\Tax\Controller\Adminhtml;
 
+use Magento\Framework\Exception\NoSuchEntityException;
+
 /**
  * @magentoAppArea adminhtml
  */
 class TaxTest extends \Magento\Backend\Utility\Controller
 {
     /**
-     * @dataProvider ajaxSaveActionDataProvider
+     * @dataProvider ajaxActionDataProvider
      * @magentoDbIsolation enabled
      *
      * @param array $postData
@@ -52,19 +54,56 @@ class TaxTest extends \Magento\Backend\Utility\Controller
 
         $classId = $result['class_id'];
         /** @var $rate \Magento\Tax\Model\ClassModel */
-        $class = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Tax\Model\ClassModel'
-        )->load(
-            $classId,
-            'class_id'
-        );
+        $class = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Tax\Model\ClassModel')
+            ->load($classId, 'class_id');
         $this->assertEquals($expectedData['class_name'], $class->getClassName());
     }
 
+    /**
+     * @dataProvider ajaxActionDataProvider
+     * @magentoDbIsolation enabled
+     *
+     * @param array $taxClassData
+     */
+    public function testAjaxDeleteAction($taxClassData)
+    {
+        $taxClassService = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Tax\Service\V1\TaxClassServiceInterface'
+        );
+
+        $taxClassBuilder = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
+            'Magento\Tax\Service\V1\Data\TaxClassBuilder'
+        );
+
+        $taxClass = $taxClassBuilder->setClassName($taxClassData['class_name'])
+            ->setClassType($taxClassData['class_type'])
+            ->create();
+
+        $taxClassId = $taxClassService->createTaxClass($taxClass);
+
+        /** @var $rate \Magento\Tax\Model\ClassModel */
+        $class = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Tax\Model\ClassModel')
+            ->load($taxClassId, 'class_id');
+        $this->assertEquals($taxClassData['class_name'], $class->getClassName());
+        $this->assertEquals($taxClassData['class_type'], $class->getClassType());
+
+        $postData = [ 'class_id' => $taxClassId ];
+        $this->getRequest()->setPost($postData);
+        $this->dispatch('backend/tax/tax/ajaxDelete');
+
+        $isFound = true;
+        try {
+            $taxClassId = $taxClassService->getTaxClass($taxClassId);
+        } catch (NoSuchEntityException $e) {
+            $isFound = false;
+        }
+        $this->assertFalse($isFound, "Tax Class was found when it should have been deleted.");
+    }
+
     /**
      * @return array
      */
-    public function ajaxSaveActionDataProvider()
+    public function ajaxActionDataProvider()
     {
         return array(
             array(
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Helper/DataTest.php b/dev/tests/integration/testsuite/Magento/Tax/Helper/DataTest.php
index 7d9c122825c4b3ea7fa7b2e1fe59309447215516..bafb54e5c3ca5827f164893cbd99fbc3f5b1631e 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Helper/DataTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Helper/DataTest.php
@@ -23,16 +23,84 @@
  */
 namespace Magento\Tax\Helper;
 
+use Magento\Tax\Model\ClassModel;
+use Magento\Tax\Service\V1\TaxRuleFixtureFactory;
+use Magento\Store\Model\ScopeInterface;
+use Magento\Tax\Model\Config;
+
 class DataTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * Tax helper
+     *
+     * @var \Magento\Tax\Helper\Data
+     */
+    private $helper;
+
+    /**
+     * Object Manager
+     *
+     * @var \Magento\Framework\ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * Array of default tax classes ids
+     *
+     * Key is class name
+     *
+     * @var int[]
+     */
+    private $taxClasses;
+
+    /**
+     * Array of default tax rates ids.
+     *
+     * Key is rate percentage as string.
+     *
+     * @var int[]
+     */
+    private $taxRates;
+
+    /**
+     * Array of default tax rules ids.
+     *
+     * Key is rule code.
+     *
+     * @var int[]
+     */
+    private $taxRules;
+
+    /**
+     * Helps in creating required tax rules.
+     *
+     * @var TaxRuleFixtureFactory
+     */
+    private $taxRuleFixtureFactory;
+
+    /** @var \Magento\Framework\App\MutableScopeConfig */
+    private $scopeConfig;
+
+    public function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        /** @var $helper \Magento\Tax\Helper\Data */
+        $this->helper = $this->objectManager->get('Magento\Tax\Helper\Data');
+        $this->taxRuleFixtureFactory = new TaxRuleFixtureFactory();
+        $this->scopeConfig = $this->objectManager->get('Magento\Framework\App\MutableScopeConfig');
+    }
+
+    protected function tearDown()
+    {
+        $this->tearDownDefaultRules();
+    }
+
     /**
      * @magentoConfigFixture default_store tax/classes/default_customer_tax_class 1
      */
     public function testGetDefaultCustomerTaxClass()
     {
-        /** @var $helper \Magento\Tax\Helper\Data */
-        $helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Tax\Helper\Data');
-        $this->assertEquals(1, $helper->getDefaultCustomerTaxClass());
+        $this->assertEquals(1, $this->helper->getDefaultCustomerTaxClass());
     }
 
     /**
@@ -40,8 +108,265 @@ class DataTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetDefaultProductTaxClass()
     {
-        /** @var $helper \Magento\Tax\Helper\Data */
-        $helper = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get('Magento\Tax\Helper\Data');
-        $this->assertEquals(1, $helper->getDefaultProductTaxClass());
+        $this->assertEquals(1, $this->helper->getDefaultProductTaxClass());
+    }
+
+    /**
+     * @param \Magento\Framework\Object $input
+     * @param float $expectOutputPrice
+     * @param string[] $configs
+     * @param string $productClassName
+     *
+     * @magentoDataFixture Magento/Catalog/_files/products.php
+     * @magentoDataFixture Magento/Customer/_files/customer.php
+     * @magentoDataFixture Magento/Customer/_files/customer_address.php
+     * @magentoDbIsolation enabled
+     * @dataProvider getPriceDataProvider
+     */
+    public function testGetPrice($input, $expectOutputPrice, $configs = [], $productClassName = 'DefaultProductClass')
+    {
+        $this->setUpDefaultRules();
+        $fixtureProductId = 1;
+        /** @var \Magento\Catalog\Model\Product $product */
+        $product = $this->objectManager->create('Magento\Catalog\Model\Product')->load($fixtureProductId);
+        $product->setTaxClassId($this->taxClasses[$productClassName]);
+        $shippingAddress = $this->getCustomerAddress();
+        $billingAddress = $shippingAddress;
+        foreach ($configs as $config) {
+            $this->scopeConfig->setValue($config['path'], $config['value'], ScopeInterface::SCOPE_STORE, 'default');
+        }
+
+        $price = $this->helper->getPrice(
+            $product,
+            $input->getPrice(),
+            $input->getIncludingTax(),
+            $shippingAddress,
+            $billingAddress,
+            $this->taxClasses['DefaultCustomerClass'],
+            $input->getStore(),
+            $input->getPriceIncludesTax(),
+            $input->getRoundPrice()
+        );
+        $this->assertEquals($expectOutputPrice, $price);
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function getPriceDataProvider()
+    {
+        return [
+            'price is 0' => [
+                (new \Magento\Framework\Object())->setPrice(0),
+                0
+            ],
+            'no price conversion, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '3.26'
+            ],
+            'no price conversion, no round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256),
+                '3.256'
+            ],
+            'price conversion, display including tax, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '3.5',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '0',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_INCLUDING_TAX,
+                    ],
+                ]
+            ],
+            'price conversion, display including tax, no round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256),
+                '3.5',  // rounding issue: old code expects 3.5002
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '0',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_INCLUDING_TAX,
+                    ],
+                ]
+            ],
+            'price conversion, display including tax, high rate product tax class, cross boarder trade, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '3.98', // rounding issue: old code expects 3.97
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '0',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_INCLUDING_TAX,
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED,
+                        'value' => '1',
+                    ],
+                ],
+                'HigherProductClass',
+            ],
+            'price include tax, display including tax, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '3.26',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '1',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_INCLUDING_TAX,
+                    ],
+                ]
+            ],
+            'price include tax, display excluding tax, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '3.03',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '1',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_EXCLUDING_TAX,
+                    ],
+                ]
+            ],
+            'price include tax, display excluding tax, request including tax, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)
+                    ->setRoundPrice(true)
+                    ->setIncludingTax(true),
+                '3.26',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '1',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_EXCLUDING_TAX,
+                    ],
+                ]
+            ],
+            'price include tax, display excluding tax, high rate product tax class, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '2.67',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '1',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_EXCLUDING_TAX,
+                    ],
+                ],
+                'HigherProductClass',
+            ],
+            'price include tax, display excluding tax, high rate product tax class, cross boarder trade, round' => [
+                (new \Magento\Framework\Object())->setPrice(3.256)->setRoundPrice(true),
+                '2.67',
+                [
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_INCLUDES_TAX,
+                        'value' => '1',
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_PRICE_DISPLAY_TYPE,
+                        'value' => Config::DISPLAY_TYPE_EXCLUDING_TAX,
+                    ],
+                    [
+                        'path' => Config::CONFIG_XML_PATH_CROSS_BORDER_TRADE_ENABLED,
+                        'value' => '1',
+                    ],
+                ],
+                'HigherProductClass',
+            ],
+        ];
+    }
+
+    /**
+     * Helper function that sets up some default rules
+     */
+    private function setUpDefaultRules()
+    {
+        $this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([
+                ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER],
+                ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
+                ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
+            ]);
+
+        $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([
+                ['percentage' => 7.5, 'country' => 'US', 'region' => 42],
+                ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate
+            ]);
+
+        $higherRates = $this->taxRuleFixtureFactory->createTaxRates([
+                ['percentage' => 22, 'country' => 'US', 'region' => 42],
+                ['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate
+            ]);
+
+        $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([
+                [
+                    'code' => 'Default Rule',
+                    'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                    'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']],
+                    'tax_rate_ids' => array_values($this->taxRates),
+                    'sort_order' => 0,
+                    'priority' => 0,
+                ],
+                [
+                    'code' => 'Higher Rate Rule',
+                    'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                    'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']],
+                    'tax_rate_ids' => array_values($higherRates),
+                    'sort_order' => 0,
+                    'priority' => 0,
+                ],
+            ]);
+
+        // For cleanup
+        $this->taxRates = array_merge($this->taxRates, $higherRates);
+    }
+
+    /**
+     * Helper function that tears down some default rules
+     */
+    private function tearDownDefaultRules()
+    {
+        if ($this->taxRules) {
+            $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules));
+        }
+        if ($this->taxRates) {
+            $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates));
+        }
+        if ($this->taxClasses) {
+            $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses));
+        }
+    }
+
+    /**
+     * Get fixture customer address
+     *
+     * @return \Magento\Customer\Model\Address
+     */
+    private function getCustomerAddress()
+    {
+        $fixtureCustomerId = 1;
+        $customerAddress = $this->objectManager->create('Magento\Customer\Model\Address')->load($fixtureCustomerId);
+        /** Set data which corresponds tax class fixture */
+        $customerAddress->setCountryId('US')->setRegionId(42)->save();
+        return $customerAddress;
     }
 }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RuleTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RuleTest.php
deleted file mode 100644
index 17eeab5a50c143cc2653e4b6b05b79202f4a9131..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Calculation/RuleTest.php
+++ /dev/null
@@ -1,226 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Tax\Model\Calculation;
-
-/**
- * @magentoDataFixture Magento/Tax/_files/tax_classes.php
- */
-class RuleTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @var \Magento\Framework\ObjectManager
-     */
-    protected $_objectManager;
-
-    protected function setUp()
-    {
-        $this->_objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-    }
-
-    /**
-     * Test that first value in multiselect applied as default if there is no default value in config
-     *
-     * @magentoConfigFixture default_store tax/classes/default_customer_tax_class 0
-     */
-    public function testGetCustomerTaxClassWithDefaultFirstValue()
-    {
-        $taxClass = $this->_getTaxClassMock(
-            'getCustomerClasses',
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER
-        );
-        $model = $this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rule',
-            array('taxClass' => $taxClass, 'registry' => $this->_getRegistryClassMock())
-        );
-        $this->assertEquals(1, $model->getCustomerTaxClassWithDefault());
-    }
-
-    /**
-     * Test that default value for multiselect is retrieve from config
-     *
-     * @magentoConfigFixture default_store tax/classes/default_customer_tax_class 2
-     */
-    public function testGetCustomerTaxClassWithDefaultFromConfig()
-    {
-        $taxClass = $this->_getTaxClassMock(
-            'getCustomerClasses',
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER
-        );
-        $model = $this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rule',
-            array('taxClass' => $taxClass, 'registry' => $this->_getRegistryClassMock())
-        );
-        $this->assertEquals(2, $model->getCustomerTaxClassWithDefault());
-    }
-
-    /**
-     * Test that first value in multiselect applied as default if there is no default value in config
-     *
-     * @magentoConfigFixture default_store tax/classes/default_product_tax_class 0
-     */
-    public function testGetProductTaxClassWithDefaultFirstValue()
-    {
-        $taxClass = $this->_getTaxClassMock(
-            'getProductClasses',
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
-        );
-        $model = $this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rule',
-            array('taxClass' => $taxClass, 'registry' => $this->_getRegistryClassMock())
-        );
-        $this->assertEquals(1, $model->getProductTaxClassWithDefault());
-    }
-
-    /**
-     * Test that default value for multiselect is retrieve from config
-     *
-     * @magentoConfigFixture default_store tax/classes/default_product_tax_class 2
-     */
-    public function testGetProductTaxClassWithDefaultFromConfig()
-    {
-        $taxClass = $this->_getTaxClassMock(
-            'getProductClasses',
-            \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT
-        );
-        $model = $this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rule',
-            array('taxClass' => $taxClass, 'registry' => $this->_getRegistryClassMock())
-        );
-        $this->assertEquals(2, $model->getProductTaxClassWithDefault());
-    }
-
-    /**
-     * Test get all options
-     *
-     * @dataProvider getAllOptionsProvider
-     */
-    public function testGetAllOptions($classFilter, $expected)
-    {
-        $model = $this->_objectManager->create(
-            'Magento\Tax\Model\Calculation\Rule',
-            array('registry' => $this->_getRegistryClassMock())
-        );
-        $classes = $model->getAllOptionsForClass($classFilter);
-        $this->assertCount(count($expected), $classes);
-        $count = 0;
-        foreach ($classes as $class) {
-            $this->assertEquals($expected[$count], $class['label']);
-            $count++;
-        }
-    }
-
-    /**
-     * Data provider for testGetAllOptions() method
-     */
-    public function getAllOptionsProvider()
-    {
-        return array(
-            array(
-                \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER,
-                array('Retail Customer', 'CustomerTaxClass1', 'CustomerTaxClass2')
-            ),
-            array(
-                \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_PRODUCT,
-                array('Taxable Goods', 'ProductTaxClass1', 'ProductTaxClass2')
-            )
-        );
-    }
-
-    /**
-     * @return \Magento\Framework\Registry
-     */
-    protected function _getRegistryClassMock()
-    {
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        return $objectManager->get('Magento\Framework\Registry');
-    }
-
-    /**
-     * Get Product|Customer tax class mock
-     *
-     * @param string $callback
-     * @param string $filter
-     * @return \Magento\Tax\Model\ClassModel
-     */
-    protected function _getTaxClassMock($callback, $filter)
-    {
-        $collection = $this->getMock(
-            'Magento\Tax\Model\Resource\TaxClass\Collection',
-            array('setClassTypeFilter', 'toOptionArray'),
-            array(),
-            '',
-            false
-        );
-        $collection->expects(
-            $this->any()
-        )->method(
-            'setClassTypeFilter'
-        )->with(
-            $filter
-        )->will(
-            $this->returnValue($collection)
-        );
-
-        $collection->expects(
-            $this->any()
-        )->method(
-            'toOptionArray'
-        )->will(
-            $this->returnCallback(array($this, $callback))
-        );
-
-        $mock = $this->getMock(
-            'Magento\Tax\Model\ClassModel',
-            array('getCollection'),
-            array(
-                $this->_objectManager->create('Magento\Framework\Model\Context'),
-                $this->_objectManager->get('Magento\Framework\Registry'),
-                $this->_objectManager->get('Magento\Tax\Model\TaxClass\Factory')
-            ),
-            '',
-            true
-        );
-        $mock->expects($this->any())->method('getCollection')->will($this->returnValue($collection));
-
-        return $mock;
-    }
-
-    /**
-     * Prepare Customer Tax Classes
-     * @return array
-     */
-    public function getCustomerClasses()
-    {
-        return array(array('value' => '1', 'name' => 'Retail Customer'), array('value' => '2', 'name' => 'Guest'));
-    }
-
-    /**
-     * Prepare Product Tax classes
-     * @return array
-     */
-    public function getProductClasses()
-    {
-        return array(array('value' => '1', 'name' => 'Taxable Goods'), array('value' => '2', 'name' => 'Shipping'));
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/CalculationTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/CalculationTest.php
index 1b99ab9632ca2c2fe89dd9449a8d373bc642039c..851f503a9c31efb414f5b8bc4917408db38fe46d 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/CalculationTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/CalculationTest.php
@@ -76,15 +76,6 @@ class CalculationTest extends \PHPUnit_Framework_TestCase
         $this->_groupService = $this->_objectManager->create('Magento\Customer\Service\V1\CustomerGroupService');
     }
 
-    public function testSetCustomerData()
-    {
-        $customerDataSet = $this->_customerAccountService->getCustomer(self::FIXTURE_CUSTOMER_ID);
-        $this->_model->setCustomerData($customerDataSet);
-
-        $customerDataRetrieved = $this->_model->getCustomerData();
-        $this->assertEquals($customerDataSet->__toArray(), $customerDataRetrieved->__toArray());
-    }
-
     public function testDefaultCustomerTaxClass()
     {
         $defaultCustomerTaxClass = 3;
@@ -94,10 +85,9 @@ class CalculationTest extends \PHPUnit_Framework_TestCase
     public function testGetDefaultRateRequest()
     {
         $customerDataSet = $this->_customerAccountService->getCustomer(self::FIXTURE_CUSTOMER_ID);
-        $this->_model->setCustomerData($customerDataSet);
         $address = $this->_addressService->getAddress(self::FIXTURE_ADDRESS_ID);
 
-        $rateRequest = $this->_model->getRateRequest();
+        $rateRequest = $this->_model->getRateRequest(null, null, null, null, $customerDataSet->getId());
 
         $this->assertNotNull($rateRequest);
         $this->assertEquals($address->getCountryId(), $rateRequest->getCountryId());
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/ClassTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/ClassTest.php
index 29f92bb2beed3baeb586ac7edd8b9b9e4e877e2c..738a43aecbc87d1d427141297ea8878b603ccd0e 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/ClassTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/ClassTest.php
@@ -48,7 +48,7 @@ class ClassTest extends \PHPUnit_Framework_TestCase
             \Magento\Tax\Model\ClassModel::TAX_CLASS_TYPE_CUSTOMER
         )->getFirstItem();
 
-        $this->setExpectedException('Magento\Framework\Model\Exception');
+        $this->setExpectedException('Magento\Framework\Exception\CouldNotDeleteException');
         $model->delete();
     }
 
@@ -90,7 +90,7 @@ class ClassTest extends \PHPUnit_Framework_TestCase
             $model->getId()
         )->save();
 
-        $this->setExpectedException('Magento\Framework\Model\Exception');
+        $this->setExpectedException('Magento\Framework\Exception\CouldNotDeleteException');
         $model->delete();
     }
 
@@ -131,7 +131,7 @@ class ClassTest extends \PHPUnit_Framework_TestCase
         /** @var $model \Magento\Tax\Model\ClassModel */
         $model = $this->_objectManager->create('Magento\Tax\Model\ClassModel')->load($customerClasses[0]);
         $this->setExpectedException(
-            'Magento\Framework\Model\Exception',
+            'Magento\Framework\Exception\CouldNotDeleteException',
             'You cannot delete this tax class because it is used in' .
             ' Tax Rules. You have to delete the rules it is used in first.'
         );
@@ -153,7 +153,7 @@ class ClassTest extends \PHPUnit_Framework_TestCase
         /** @var $model \Magento\Tax\Model\ClassModel */
         $model = $this->_objectManager->create('Magento\Tax\Model\ClassModel')->load($productClasses[0]);
         $this->setExpectedException(
-            'Magento\Framework\Model\Exception',
+            'Magento\Framework\Exception\CouldNotDeleteException',
             'You cannot delete this tax class because it is used in' .
             ' Tax Rules. You have to delete the rules it is used in first.'
         );
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/SourceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/SourceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..df51a08df070e9a041a9c8d14ff5749d767fd6da
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Rate/SourceTest.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model\Rate;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class SourceTest extends \PHPUnit_Framework_TestCase
+{
+    public function testToOptionArray()
+    {
+        /** @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\Calculation\Rate\Collection');
+        $expectedResult = [];
+        /** @var $taxRate \Magento\Tax\Model\Calculation\Rate */
+        foreach ($collection as $taxRate) {
+            $expectedResult[] = ['value' => $taxRate->getId(), 'label' => $taxRate->getCode()];
+        }
+        /** @var \Magento\Tax\Model\Rate\Source $source */
+        if (empty($expectedResult)) {
+            $this->fail('Preconditions failed: At least one tax rate should be available.');
+        }
+        $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Rate\Source');
+        $this->assertEquals(
+            $expectedResult,
+            $source->toOptionArray(),
+            'Tax rate options are invalid.'
+        );
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Resource/CalculationTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Resource/CalculationTest.php
index 734e6eb426027f220993eade7d0c6d11d179b21e..74f0237d4eeef38e2e6226dd6b127c312f081e4e 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Resource/CalculationTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Resource/CalculationTest.php
@@ -28,6 +28,7 @@ class CalculationTest extends \PHPUnit_Framework_TestCase
     /**
      * Test that Tax Rate applied only once
      *
+     * @magentoAppIsolation enabled
      * @magentoDataFixture Magento/Tax/_files/tax_classes.php
      */
     public function testGetRate()
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
index f8a3e8daeacccbf0e486fc82204eb3238b0cf16c..2fa9114c65b146de8ebe57089371bedb04251847 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/Sales/Total/Quote/SubtotalTest.php
@@ -126,7 +126,6 @@ class SubtotalTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($expected['items'][0]['price_incl_tax'], $item->getPriceInclTax());
         $this->assertEquals($expected['items'][0]['row_total'], $item->getRowTotal());
         $this->assertEquals($expected['items'][0]['row_total_incl_tax'], $item->getRowTotalInclTax());
-        $this->assertEquals($expected['items'][0]['taxable_amount'], $item->getTaxableAmount());
         $this->assertEquals($expected['items'][0]['tax_percent'], $item->getTaxPercent());
     }
 
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9375135fd5bd8edbb1eea46d685649b135c5b33c
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/CustomerTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model\TaxClass\Source;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class CustomerTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetAllOptions()
+    {
+        /** @var \Magento\Tax\Model\Resource\TaxClass\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\TaxClass\Collection');
+        $expectedResult = [];
+        /** @var \Magento\Tax\Model\ClassModel $taxClass */
+        foreach ($collection as $taxClass) {
+            if ($taxClass->getClassType() == \Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_CUSTOMER) {
+                $expectedResult[] = ['value' => $taxClass->getId(), 'label' => $taxClass->getClassName()];
+            }
+        }
+        if (empty($expectedResult)) {
+            $this->fail('Preconditions failed: At least one tax class should be available.');
+        }
+        /** @var \Magento\Tax\Model\TaxClass\Source\Product $source */
+        $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
+        $this->assertEquals(
+            $expectedResult,
+            $source->getAllOptions(),
+            'Tax Class options are invalid.'
+        );
+    }
+
+    public function testGetAllOptionsWithDefaultValues()
+    {
+        /** @var \Magento\Tax\Model\Resource\TaxClass\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\TaxClass\Collection');
+        $expectedResult = [];
+        /** @var \Magento\Tax\Model\ClassModel $taxClass */
+        foreach ($collection as $taxClass) {
+            if ($taxClass->getClassType() == \Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_CUSTOMER) {
+                $expectedResult[] = ['value' => $taxClass->getId(), 'label' => $taxClass->getClassName()];
+            }
+        }
+        if (empty($expectedResult)) {
+            $this->fail('Preconditions failed: At least one tax class should be available.');
+        }
+        $expectedResult = array_merge(array(array('value' => '0', 'label' => __('None'))), $expectedResult);
+        /** @var \Magento\Tax\Model\TaxClass\Source\Product $source */
+        $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Customer');
+        $this->assertEquals(
+            $expectedResult,
+            $source->getAllOptions(true),
+            'Tax Class options are invalid.'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..776403307c9d2549373ccf425dd895f7d3ae80c1
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Model/TaxClass/Source/ProductTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model\TaxClass\Source;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class ProductTest extends \PHPUnit_Framework_TestCase
+{
+    public function testGetAllOptions()
+    {
+        /** @var \Magento\Tax\Model\Resource\TaxClass\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\TaxClass\Collection');
+        $expectedResult = [];
+        /** @var \Magento\Tax\Model\ClassModel $taxClass */
+        foreach ($collection as $taxClass) {
+            if ($taxClass->getClassType() == \Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_PRODUCT) {
+                $expectedResult[] = ['value' => $taxClass->getId(), 'label' => $taxClass->getClassName()];
+            }
+        }
+        if (empty($expectedResult)) {
+            $this->fail('Preconditions failed: At least one tax class should be available.');
+        }
+        /** @var \Magento\Tax\Model\TaxClass\Source\Product $source */
+        $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Product');
+        $this->assertEquals(
+            $expectedResult,
+            $source->getAllOptions(),
+            'Tax Class options are invalid.'
+        );
+    }
+
+    public function testGetAllOptionsWithDefaultValues()
+    {
+        /** @var \Magento\Tax\Model\Resource\TaxClass\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\TaxClass\Collection');
+        $expectedResult = [];
+        /** @var \Magento\Tax\Model\ClassModel $taxClass */
+        foreach ($collection as $taxClass) {
+            if ($taxClass->getClassType() == \Magento\Tax\Service\V1\TaxClassServiceInterface::TYPE_PRODUCT) {
+                $expectedResult[] = ['value' => $taxClass->getId(), 'label' => $taxClass->getClassName()];
+            }
+        }
+        if (empty($expectedResult)) {
+            $this->fail('Preconditions failed: At least one tax class should be available.');
+        }
+        $expectedResult = array_merge(array(array('value' => '0', 'label' => __('None'))), $expectedResult);
+        /** @var \Magento\Tax\Model\TaxClass\Source\Product $source */
+        $source = Bootstrap::getObjectManager()->get('Magento\Tax\Model\TaxClass\Source\Product');
+        $this->assertEquals(
+            $expectedResult,
+            $source->getAllOptions(true),
+            'Tax Class options are invalid.'
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRateCollectionTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRateCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..898f8e9ea7be31a95062b8522ddc5402ec062160
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRateCollectionTest.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Collection;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class TaxRateCollectionTest extends \PHPUnit_Framework_TestCase
+{
+    public function testCreateTaxRateCollectionItem()
+    {
+        /** @var \Magento\Tax\Model\Resource\Calculation\Rate\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\Calculation\Rate\Collection');
+        $dbTaxRatesQty = $collection->count();
+        if (($dbTaxRatesQty == 0) || ($collection->getFirstItem()->getId() != 1)) {
+            $this->fail("Preconditions failed.");
+        }
+        /** @var \Magento\Tax\Service\V1\Collection\TaxRateCollection $taxRatesCollection */
+        $taxRatesCollection = Bootstrap::getObjectManager()
+            ->create('Magento\Tax\Service\V1\Collection\TaxRateCollection');
+        $collectionTaxRatesQty = $taxRatesCollection->count();
+        $this->assertEquals($dbTaxRatesQty, $collectionTaxRatesQty, 'Tax rates quantity is invalid.');
+        $taxRate = $taxRatesCollection->getFirstItem()->getData();
+        $expectedTaxRateData = [
+            'code' => 'US-CA-*-Rate 1',
+            'tax_calculation_rate_id' => '1',
+            'rate' => 8.25,
+            'region_name' => 'CA',
+            'tax_country_id' => 'US',
+            'tax_postcode' => '*',
+            'tax_region_id' => '12',
+            'titles' => [],
+            'zip_is_range' => null,
+            'zip_from' => null,
+            'zip_to' => null,
+        ];
+        $this->assertEquals($expectedTaxRateData, $taxRate, 'Tax rate data is invalid.');
+    }
+}
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRuleCollectionTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRuleCollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8daee990c5deb614bba023b981f008c8b133532b
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Collection/TaxRuleCollectionTest.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Service\V1\Collection;
+
+use Magento\TestFramework\Helper\Bootstrap;
+
+class TaxRuleCollectionTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @magentoAppIsolation enabled
+     * @magentoDataFixture Magento/Tax/_files/tax_classes.php
+     */
+    public function testCreateTaxRuleCollectionItem()
+    {
+        /** @var \Magento\Tax\Model\Resource\Calculation\Rule\Collection $collection */
+        $collection = Bootstrap::getObjectManager()->get('Magento\Tax\Model\Resource\Calculation\Rule\Collection');
+        $dbTaxRulesQty = $collection->count();
+
+        $firstTaxRuleFixture = Bootstrap::getObjectManager()->get('Magento\Framework\Registry')
+            ->registry('_fixture/Magento_Tax_Model_Calculation_Rule');
+        $expectedFirstTaxRuleId = $firstTaxRuleFixture->getId();
+
+        if (($dbTaxRulesQty == 0) || ($collection->getFirstItem()->getId() != $expectedFirstTaxRuleId)) {
+            $this->fail("Preconditions failed.");
+        }
+        /** @var \Magento\Tax\Service\V1\Collection\TaxRuleCollection $taxRulesCollection */
+        $taxRulesCollection = Bootstrap::getObjectManager()
+            ->create('Magento\Tax\Service\V1\Collection\TaxRuleCollection');
+        $collectionTaxRulesQty = $taxRulesCollection->count();
+        $this->assertEquals($dbTaxRulesQty, $collectionTaxRulesQty, 'Tax rules quantity is invalid.');
+        $taxRule = $taxRulesCollection->getFirstItem()->getData();
+        $expectedTaxRuleData = [
+            'tax_calculation_rule_id' => $expectedFirstTaxRuleId,
+            'code' => 'Test Rule',
+            'priority' => '0',
+            'position' => '0',
+            'calculate_subtotal' => '0',
+            'customer_tax_classes' => $firstTaxRuleFixture->getTaxCustomerClass(),
+            'product_tax_classes' => $firstTaxRuleFixture->getTaxProductClass(),
+            'tax_rates' => $firstTaxRuleFixture->getTaxRate()
+        ];
+
+        $this->assertEquals($expectedTaxRuleData, $taxRule, 'Tax rule data is invalid.');
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php
index 84556366d4b93b73d6ed2a262b0032ceb028fcd7..d7513b5f4a516c4774ccb6557480f4549933d2d5 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/QuoteDetailsBuilderTest.php
@@ -112,6 +112,14 @@ class QuoteDetailsBuilderTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($taxRate->__toArray(), $taxRateMerged->__toArray());
     }
 
+    public function testSetCustomerId()
+    {
+        $customerId = 1;
+        $this->builder->setCustomerId($customerId);
+        $quoteDetails = $this->builder->create();
+        $this->assertEquals($customerId, $quoteDetails->getCustomerId());
+    }
+
     /**
      * @return array
      */
@@ -149,10 +157,12 @@ class QuoteDetailsBuilderTest extends \PHPUnit_Framework_TestCase
                 'discount_amount' => 5
             ]
         ];
+
         $data = [
             'data1' => [
                 QuoteDetails::KEY_BILLING_ADDRESS => $addressData,
                 QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID => 1,
+                QuoteDetails::KEY_CUSTOMER_ID => 1
             ],
             'data2' => [
                 QuoteDetails::KEY_SHIPPING_ADDRESS => $addressData,
@@ -162,6 +172,7 @@ class QuoteDetailsBuilderTest extends \PHPUnit_Framework_TestCase
                 QuoteDetails::KEY_BILLING_ADDRESS => $addressData,
                 QuoteDetails::KEY_SHIPPING_ADDRESS => $addressData,
                 QuoteDetails::KEY_CUSTOMER_TAX_CLASS_ID => 1,
+                QuoteDetails::KEY_CUSTOMER_ID => 1,
                 QuoteDetails::KEY_ITEMS => $items
             ]
         ];
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxDetailsBuilderTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxDetailsBuilderTest.php
index 0d1d0f7b4cabe38a32c752e41df2b1d53ce61635..654eff8488f23f9dc97f1f66f0feb6bbecf2dfbd 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxDetailsBuilderTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxDetailsBuilderTest.php
@@ -128,12 +128,10 @@ class TaxDetailsBuilderTest extends \PHPUnit_Framework_TestCase
             'no_items' => [[
                 'subtotal' => 9.99,
                 'tax_amount' => 0.00,
-                'discount_amount' => 0.00,
             ]],
             'single_item' => [[
                 'subtotal' => 19.99,
                 'tax_amount' => 1.65,
-                'discount_amount' => 0.00,
                 'applied_taxes' => [
                     $appliedTaxDataArray,
                 ],
@@ -144,7 +142,6 @@ class TaxDetailsBuilderTest extends \PHPUnit_Framework_TestCase
             'multiple_items' => [[
                 'subtotal' => 19.99,
                 'tax_amount' => 1.65,
-                'discount_amount' => 0.00,
                 'applied_taxes' => [
                     $appliedTaxDataArray,
                     $appliedTaxDataArray,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilderTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c8b4abb9f88d226379a6dc3b8e866698f7b66806
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/Data/TaxRateSearchResultsBuilderTest.php
@@ -0,0 +1,194 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Tax\Service\V1\Data;
+
+use Magento\Framework\Service\V1\Data\SearchCriteria;
+
+/**
+ * Integration test for \Magento\Tax\Service\V1\Data\TaxRateSearchResultsBuilder
+ */
+class TaxRateSearchResultsBuilderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Object Manager
+     *
+     * @var \Magento\Framework\ObjectManager
+     */
+    private $objectManager;
+
+    /**
+     * TaxRateSearchResults builder
+     *
+     * @var TaxRateSearchResultsBuilder
+     */
+    private $taxRateSearchResultsBuilder;
+
+
+    protected function setUp()
+    {
+        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
+        $this->taxRateSearchResultsBuilder = $this->objectManager->create(
+            'Magento\Tax\Service\V1\Data\TaxRateSearchResultsBuilder'
+        );
+    }
+
+    /**
+     * @param array $dataArray
+     * @dataProvider createDataProvider
+     */
+    public function testCreateWithPopulateWithArray($dataArray)
+    {
+        $taxRateSearchResults = $this->taxRateSearchResultsBuilder->populateWithArray($dataArray)->create();
+        $this->assertInstanceOf('\Magento\Tax\Service\V1\Data\TaxRateSearchResults', $taxRateSearchResults);
+        $this->assertEquals($dataArray, $taxRateSearchResults->__toArray());
+    }
+
+    public function createDataProvider()
+    {
+        list($rateA, $rateB) = $this->getRateData();
+
+        return [
+            [[]],
+            [
+                [
+                    TaxRateSearchResults::KEY_SEARCH_CRITERIA => [
+                        SearchCriteria::CURRENT_PAGE => 1,
+                        SearchCriteria::PAGE_SIZE => 2,
+                        SearchCriteria::SORT_ORDERS => SearchCriteria::SORT_DESC,
+                        SearchCriteria::FILTER_GROUPS => [],
+                    ],
+                    TaxRateSearchResults::KEY_TOTAL_COUNT => 2,
+                    TaxRateSearchResults::KEY_ITEMS => [
+                        $rateA,
+                        $rateB
+                    ],
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * @param array $dataArray
+     * @dataProvider createDataProvider
+     */
+    public function testPopulate($dataArray)
+    {
+        $taxRateSearchResultsFromArray = $this->taxRateSearchResultsBuilder->populateWithArray($dataArray)->create();
+        $taxRateSearchResults = $this->taxRateSearchResultsBuilder->populate($taxRateSearchResultsFromArray)->create();
+        $this->assertEquals($taxRateSearchResultsFromArray, $taxRateSearchResults);
+    }
+
+    /**
+     * @dataProvider mergeDataProvider
+     */
+    public function testMergeDataObjects($firstDataSet, $secondDataSet, $mergedData)
+    {
+        $taxRateSearchResults = $this->taxRateSearchResultsBuilder->populateWithArray($mergedData)->create();
+        $taxRateSearchResults1 = $this->taxRateSearchResultsBuilder->populateWithArray($firstDataSet)->create();
+        $taxRateSearchResults2 = $this->taxRateSearchResultsBuilder->populateWithArray($secondDataSet)->create();
+        $taxRateSearchResultsMerged = $this->taxRateSearchResultsBuilder->mergeDataObjects(
+            $taxRateSearchResults1,
+            $taxRateSearchResults2
+        );
+        $this->assertEquals($taxRateSearchResults->__toArray(), $taxRateSearchResultsMerged->__toArray());
+    }
+
+    /**
+     * @dataProvider mergeDataProvider
+     */
+    public function testMergeDataObjectWithArray($firstDataSet, $secondDataSet, $mergedData)
+    {
+        $taxRateSearchResults = $this->taxRateSearchResultsBuilder->populateWithArray($mergedData)->create();
+        $taxRateSearchResults1 = $this->taxRateSearchResultsBuilder->populateWithArray($firstDataSet)->create();
+        $taxRateSearchResultsMerged = $this->taxRateSearchResultsBuilder->mergeDataObjectWithArray(
+            $taxRateSearchResults1,
+            $secondDataSet
+        );
+        $this->assertEquals($taxRateSearchResults->__toArray(), $taxRateSearchResultsMerged->__toArray());
+    }
+
+    public function mergeDataProvider()
+    {
+        list($rateA, $rateB) = $this->getRateData();
+
+        return
+            [
+                'basicMerge' => [
+                    'firstDataSet' => [
+                        TaxRateSearchResults::KEY_SEARCH_CRITERIA => [
+                            SearchCriteria::CURRENT_PAGE => 1,
+                            SearchCriteria::PAGE_SIZE => 2,
+                            SearchCriteria::SORT_ORDERS => SearchCriteria::SORT_DESC,
+                            SearchCriteria::FILTER_GROUPS => [],
+                        ],
+                        TaxRateSearchResults::KEY_ITEMS => [
+                            $rateA
+                        ],
+                    ],
+                    'SecondDataSet' => [
+                        TaxRateSearchResults::KEY_SEARCH_CRITERIA => [
+                            SearchCriteria::CURRENT_PAGE => 1,
+                            SearchCriteria::PAGE_SIZE => 2,
+                            SearchCriteria::SORT_ORDERS => SearchCriteria::SORT_DESC,
+                            SearchCriteria::FILTER_GROUPS => [],
+                        ],
+                        TaxRateSearchResults::KEY_TOTAL_COUNT => 2,
+                        TaxRateSearchResults::KEY_ITEMS => [
+                            $rateB
+                        ],
+                    ],
+                    'mergedData' => [
+                        TaxRateSearchResults::KEY_SEARCH_CRITERIA => [
+                            SearchCriteria::CURRENT_PAGE => 1,
+                            SearchCriteria::PAGE_SIZE => 2,
+                            SearchCriteria::SORT_ORDERS => SearchCriteria::SORT_DESC,
+                            SearchCriteria::FILTER_GROUPS => [],
+                        ],
+                        TaxRateSearchResults::KEY_TOTAL_COUNT => 2,
+                        TaxRateSearchResults::KEY_ITEMS => [
+                            $rateB
+                        ],
+                    ]
+                ]
+            ];
+    }
+
+    private function getRateData()
+    {
+        $rateA = [
+            TaxRate::KEY_ID => 1,
+            TaxRate::KEY_COUNTRY_ID => 'US',
+            TaxRate::KEY_REGION_ID => '8',
+            TaxRate::KEY_PERCENTAGE_RATE => '8.25',
+            TaxRate::KEY_CODE => 'US-CA-*-Rate 1',
+            TaxRate::KEY_POSTCODE => '78728'
+        ];
+
+        $rateB = [
+            TaxRate::KEY_ID => 1,
+            TaxRate::KEY_ZIP_RANGE => ['from' => 78701, 'to' => 78780],
+        ];
+        return ([$rateA, $rateB]);
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php
index 146a1c126fe48eca636e49c475b1f050efcfb8bf..1638d8bc15b40424b9211e25a5652488513beb26 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxCalculationServiceTest.php
@@ -142,17 +142,46 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $oneProductResults = [
             'subtotal' => 20,
             'tax_amount' => 1.5,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 1.5,
+                    'percent' => 7.5,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                            'percent' => 7.5
+                        ]
+                    ],
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
                     'row_tax' => 1.5,
                     'price' => 10,
                     'price_incl_tax' => 10.75,
                     'row_total' => 20,
-                    'taxable_amount' => 10,
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 21.5,
                     'type' => 'product',
                     'tax_percent' => 7.5,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 1.5,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -163,13 +192,10 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'product',
             'quantity' => 2,
             'unit_price' => 10.75,
-            'row_total' => 21.5,
             'tax_class_id' => 'DefaultProductClass',
             'tax_included' => true,
         ];
         $oneProductInclTaxResults = $oneProductResults;
-        // TODO: I think this is a bug, but the old code behaved this way so keeping it for now.
-        $oneProductInclTaxResults['items'][0]['taxable_amount'] = 10.75;
 
         $oneProductInclTaxDiffRate = $baseQuote;
         $oneProductInclTaxDiffRate['items'][] = [
@@ -177,24 +203,52 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'product',
             'quantity' => 2,
             'unit_price' => 11,
-            'row_total' => 22,
             'tax_class_id' => 'HigherProductClass',
             'tax_included' => true,
         ];
         $oneProductInclTaxDiffRateResults = [
             'subtotal' => 20,
             'tax_amount' => 4.4,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 4.4,
+                    'percent' => 22,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 22',
+                            'title' => 'US - 42 - 22',
+                            'percent' => 22,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 22',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => 4.4,
                     'price' => 10,
                     'price_incl_tax' => 12.2,
                     'row_total' => 20,
-                    'taxable_amount' => 12.2, // TODO: Possible bug, shouldn't this be 10?
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 24.4,
                     'type' => 'product',
                     'tax_percent' => 22.0,
-                    'row_tax' => 4.4,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 22' => [
+                            'amount' => 4.4,
+                            'percent' => 22,
+                            'tax_rate_key' => 'US - 42 - 22',
+                            'rates' => [
+                                'US - 42 - 22' => [
+                                    'percent' => 22,
+                                    'code' => 'US - 42 - 22',
+                                    'title' => 'US - 42 - 22',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -206,7 +260,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                 'type' => 'product',
                 'quantity' => 2,
                 'unit_price' => 10,
-                'row_total' => 20,
                 'tax_class_id' => 'DefaultProductClass',
             ],
             [
@@ -214,34 +267,77 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                 'type' => 'product',
                 'quantity' => 20,
                 'unit_price' => 11,
-                'row_total' => 220,
                 'tax_class_id' => 'DefaultProductClass',
             ]
         ];
         $twoProductsResults = [
             'subtotal' => 240,
             'tax_amount' => 18.1,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 18.1,
+                    'percent' => 7.5,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                            'percent' => 7.5,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => 1.5,
                     'price' => 10,
                     'price_incl_tax' => 10.75,
                     'row_total' => 20,
-                    'taxable_amount' => 10,
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 21.5,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => 1.5,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 1.5,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
-                [
+                'sku_2' =>                 [
+                    'code' => 'sku_2',
+                    'row_tax' => 16.6,
                     'price' => 11,
                     'price_incl_tax' => 11.83,
                     'row_total' => 220,
-                    'taxable_amount' => 11,
-                    'code' => 'sku_2',
+                    'row_total_incl_tax' => 236.6,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => 16.6,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 16.6,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -268,9 +364,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             ]
         ];
         $twoProductInclTaxResults = $twoProductsResults;
-        // TODO: I think this is a bug, but the old code behaved this way so keeping it for now.
-        $twoProductInclTaxResults['items'][0]['taxable_amount'] = 10.75;
-        $twoProductInclTaxResults['items'][1]['taxable_amount'] = 11.83;
 
         $bundleProduct = $baseQuote;
         $bundleProduct['items'][] = [
@@ -278,7 +371,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'product',
             'quantity' => 1,
             'unit_price' => 10,
-            'row_total' => 10,
             'tax_class_id' => 'DefaultProductClass',
             'parent_code' => 'bundle',
         ];
@@ -287,23 +379,61 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'product',
             'quantity' => 2,
             'unit_price' => 0,
-            'row_total' => 0,
             'tax_class_id' => 'DefaultProductClass',
         ];
         $bundleProductResults = [
             'subtotal' => 20,
             'tax_amount' => 1.5,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 1.5,
+                    'percent' => 7.5,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                            'percent' => 7.5,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
                     'row_tax' => 1.5,
                     'price' => 10,
                     'price_incl_tax' => 10.75,
                     'row_total' => 20,
-                    'taxable_amount' => 10,
-                    'code' => 'bundle',
+                    'row_total_incl_tax' => 21.5,
                     'type' => 'product',
+                    'tax_percent' => 7.5,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 1.5,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ]
+                            ],
+                        ],
+                    ],
                 ],
+                'bundle' => [
+                    'price' => 10,
+                    'price_incl_tax' => 10.75,
+                    'row_total' => 20,
+                    'row_total_incl_tax' => 21.5,
+                    'row_tax' => 1.5,
+                    'code' => 'bundle',
+                    'type' => 'product',
+                ]
             ],
         ];
 
@@ -377,7 +507,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                         'type' => 'type',
                         'quantity' => 1,
                         'unit_price' => 10.0,
-                        'row_total' => 10.0,
                         'tax_included' => false,
                     ],
                 ],
@@ -386,7 +515,8 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'expected_tax_details' => [
                 'subtotal' => 10.0,
                 'tax_amount' => 0.0,
-                'discount_amount' => 0.0,
+                'discount_tax_compensation_amount' => 0.0,
+                'applied_taxes' => [],
                 'items' => [],
             ],
             'store_id' => null,
@@ -397,33 +527,71 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'type',
             'quantity' => 1,
             'unit_price' => 10.0,
-            'row_total' => 10.0,
             'tax_included' => false,
         ];
 
+        $quoteDetailAppliedTaxesBase = [
+            [
+                'amount' => 0.75,
+                'percent' => 7.5,
+                'rates' => [
+                    [
+                        'code' => 'US - 42 - 7.5',
+                        'title' => 'US - 42 - 7.5',
+                        'percent' => 7.5,
+                    ],
+                ],
+                'tax_rate_key' => 'US - 42 - 7.5',
+            ],
+        ];
+
+        $itemDetailAppliedTaxesBase = [
+            'US - 42 - 7.5' => [
+                'amount' => 0.75,
+                'percent' => 7.5,
+                'tax_rate_key' => 'US - 42 - 7.5',
+                'rates' => [
+                    'US - 42 - 7.5' => [
+                        'percent' => 7.5,
+                        'code' => 'US - 42 - 7.5',
+                        'title' => 'US - 42 - 7.5',
+                    ],
+                ],
+            ],
+        ];
+
         $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase;
         $quoteDetailItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass';
 
         $prodExpectedItemWithNoProductTaxClass = [
-            'row_tax' => 0,
-            'price' => 10.0,
-            'price_incl_tax' => 10.0,
-            'row_total' => 10.0,
-            'taxable_amount' => 10.0,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 0,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 0,
+                'price' => 10.0,
+                'price_incl_tax' => 10.0,
+                'row_total' => 10.0,
+                'row_total_incl_tax' => 10.0,
+                'type' => 'type',
+                'tax_percent' => 0,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => [],
+            ],
         ];
 
+        $itemAppliedTaxes = $itemDetailAppliedTaxesBase;
         $prodExpectedItemWithDefaultProductTaxClass = [
-            'row_tax' => 0.75,
-            'price' => 10.0,
-            'price_incl_tax' => 10.75,
-            'row_total' => 10.0,
-            'taxable_amount' => 10.0,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 7.5,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 0.75,
+                'price' => 10.0,
+                'price_incl_tax' => 10.75,
+                'row_total' => 10.0,
+                'row_total_incl_tax' => 10.75,
+                'type' => 'type',
+                'tax_percent' => 7.5,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => $itemAppliedTaxes,
+            ],
         ];
 
         $prodWithStoreIdWithTaxClassId = $prodNoTaxInclBase;
@@ -434,22 +602,24 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $prodWithStoreIdWithTaxClassId['store_id'] = 1;
         $prodWithStoreIdWithTaxClassId['quote_details']['items'][] = $quoteDetailItemWithDefaultProductTaxClass;
         $prodWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.75;
-        $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $prodWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
+        $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithDefaultProductTaxClass;
 
         $prodWithStoreIdWithoutTaxClassId['store_id'] = 1;
         $prodWithStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
-        $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithNoProductTaxClass;
 
         $prodWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
             $quoteDetailItemWithDefaultProductTaxClass;
         $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.75;
-        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
+        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithDefaultProductTaxClass;
 
         $prodWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
-        $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithNoProductTaxClass;
 
         return [
@@ -478,7 +648,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                         'type' => 'type',
                         'quantity' => 1,
                         'unit_price' => 10.0,
-                        'row_total' => 10.0,
                         'tax_included' => true,
                     ],
                 ],
@@ -487,7 +656,8 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'expected_tax_details' => [
                 'subtotal' => 10.0,
                 'tax_amount' => 0.0,
-                'discount_amount' => 0.0,
+                'discount_tax_compensation_amount' => 0.0,
+                'applied_taxes' => [],
                 'items' => [],
             ],
             'store_id' => null,
@@ -498,7 +668,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'type',
             'quantity' => 1,
             'unit_price' => 10.0,
-            'row_total' => 10.0,
             'tax_included' => true,
         ];
 
@@ -506,25 +675,61 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $quoteDetailTaxInclItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass';
 
         $productTaxInclExpectedItemWithNoProductTaxClass = [
-            'row_tax' => 0,
-            'price' => 10.0,
-            'price_incl_tax' => 10.0,
-            'row_total' => 10.0,
-            'taxable_amount' => 10.0,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 0,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 0,
+                'price' => 10.0,
+                'price_incl_tax' => 10.0,
+                'row_total' => 10.0,
+                'row_total_incl_tax' => 10.0,
+                'type' => 'type',
+                'tax_percent' => 0,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => [],
+            ],
+        ];
+
+        $quoteDetailAppliedTaxesBase = [
+            [
+                'amount' => 0.70,
+                'percent' => 7.5,
+                'rates' => [
+                    [
+                        'code' => 'US - 42 - 7.5',
+                        'title' => 'US - 42 - 7.5',
+                        'percent' => 7.5,
+                    ],
+                ],
+                'tax_rate_key' => 'US - 42 - 7.5',
+            ],
         ];
 
         $productTaxInclExpectedItemWithDefaultProductTaxClass = [
-            'row_tax' => 0.70,
-            'price' => 9.30,
-            'price_incl_tax' => 10.00,
-            'row_total' => 9.30,
-            'taxable_amount' => 9.30,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 7.5,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 0.70,
+                'price' => 9.30,
+                'price_incl_tax' => 10.00,
+                'row_total' => 9.30,
+                'row_total_incl_tax' => 10.00,
+                'type' => 'type',
+                'tax_percent' => 7.5,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => [
+                    'US - 42 - 7.5' => [
+                        'amount' => 0.7,
+                        'percent' => 7.5,
+                        'tax_rate_key' => 'US - 42 - 7.5',
+                        'rates' => [
+                            'US - 42 - 7.5' => [
+                                'percent' => 7.5,
+                                'code' => 'US - 42 - 7.5',
+                                'title' => 'US - 42 - 7.5',
+                            ],
+                        ],
+                    ],
+                ],
+            ],
         ];
 
         $productInclTaxWithStoreIdWithTaxClassId = $productTaxInclBase;
@@ -537,27 +742,28 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             $quoteDetailTaxInclItemWithDefaultProductTaxClass;
         $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.70;
         $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['subtotal'] = 9.30;
-        $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
+            $quoteDetailAppliedTaxesBase;
+        $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $productTaxInclExpectedItemWithDefaultProductTaxClass;
-        $productInclTaxWithStoreIdWithTaxClassId['expected_tax_details']['items'][0]['taxable_amount'] = 10.00;
 
         $productInclTaxWithStoreIdWithoutTaxClassId['store_id'] = 1;
         $productInclTaxWithStoreIdWithoutTaxClassId['quote_details']['items'][] =
             $productTaxInclQuoteDetailItemBase;
-        $productInclTaxWithStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $productInclTaxWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $productTaxInclExpectedItemWithNoProductTaxClass;
 
         $productInclTaxWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
             $quoteDetailTaxInclItemWithDefaultProductTaxClass;
         $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 0.70;
         $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['subtotal'] = 9.30;
-        $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
+            $quoteDetailAppliedTaxesBase;
+        $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $productTaxInclExpectedItemWithDefaultProductTaxClass;
-        /* TODO: BUG? */
-        $productInclTaxWithoutStoreIdWithTaxClassId['expected_tax_details']['items'][0]['taxable_amount'] = 10.00;
 
         $productInclTaxWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $productTaxInclQuoteDetailItemBase;
-        $productInclTaxWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $productInclTaxWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $productTaxInclExpectedItemWithNoProductTaxClass;
 
         return [
@@ -568,6 +774,9 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
     public function calculateTaxRoundingDataProvider()
     {
         $prodRoundingNoTaxInclBase = [
@@ -583,7 +792,6 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                         'type' => 'type',
                         'quantity' => 2,
                         'unit_price' => 7.97,
-                        'row_total' => 15.94,
                         'tax_included' => false,
                     ],
                 ],
@@ -592,7 +800,8 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'expected_tax_details' => [
                 'subtotal' => 15.94,
                 'tax_amount' => 0.0,
-                'discount_amount' => 0.0,
+                'discount_tax_compensation_amount' => 0.0,
+                'applied_taxes' => [],
                 'items' => [],
             ],
             'store_id' => null,
@@ -603,33 +812,69 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             'type' => 'type',
             'quantity' => 2,
             'unit_price' => 7.97,
-            'row_total' => 15.94,
             'tax_included' => false,
         ];
 
         $quoteDetailItemWithDefaultProductTaxClass = $prodQuoteDetailItemBase;
         $quoteDetailItemWithDefaultProductTaxClass['tax_class_id'] = 'DefaultProductClass';
 
+
+        $quoteDetailAppliedTaxesBase = [
+            [
+                'amount' => 1.20,
+                'percent' => 7.5,
+                'rates' => [
+                    [
+                        'code' => 'US - 42 - 7.5',
+                        'title' => 'US - 42 - 7.5',
+                        'percent' => 7.5,
+                    ],
+                ],
+                'tax_rate_key' => 'US - 42 - 7.5',
+            ],
+        ];
+
         $prodExpectedItemWithNoProductTaxClass = [
-            'row_tax' => 0,
-            'price' => 7.97,
-            'price_incl_tax' => 7.97,
-            'row_total' => 15.94,
-            'taxable_amount' => 15.94,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 0,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 0,
+                'price' => 7.97,
+                'price_incl_tax' => 7.97,
+                'row_total' => 15.94,
+                'row_total_incl_tax' => 15.94,
+                'type' => 'type',
+                'tax_percent' => 0,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => [],
+            ],
         ];
 
         $prodExpectedItemWithDefaultProductTaxClass = [
-            'row_tax' => 1.20,
-            'price' => 7.97,
-            'price_incl_tax' => 8.57,
-            'row_total' => 15.94,
-            'taxable_amount' => 15.94,
-            'code' => 'code',
-            'type' => 'type',
-            'tax_percent' => 7.5,
+            'code' => [
+                'code' => 'code',
+                'row_tax' => 1.20,
+                'price' => 7.97,
+                'price_incl_tax' => 8.57,
+                'row_total' => 15.94,
+                'row_total_incl_tax' => 17.14,
+                'type' => 'type',
+                'tax_percent' => 7.5,
+                'discount_tax_compensation_amount' => 0,
+                'applied_taxes' => [
+                    'US - 42 - 7.5' => [
+                        'amount' => 1.2,
+                        'percent' => 7.5,
+                        'tax_rate_key' => 'US - 42 - 7.5',
+                        'rates' => [
+                            'US - 42 - 7.5' => [
+                                'percent' => 7.5,
+                                'code' => 'US - 42 - 7.5',
+                                'title' => 'US - 42 - 7.5',
+                            ],
+                        ],
+                    ],
+                ]
+            ],
         ];
 
         $prodWithStoreIdWithTaxClassId = $prodRoundingNoTaxInclBase;
@@ -640,22 +885,25 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $prodWithStoreIdWithTaxClassId['store_id'] = 1;
         $prodWithStoreIdWithTaxClassId['quote_details']['items'][] = $quoteDetailItemWithDefaultProductTaxClass;
         $prodWithStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 1.20;
-        $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $prodWithStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] = $quoteDetailAppliedTaxesBase;
+        $prodWithStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithDefaultProductTaxClass;
 
         $prodWithStoreIdWithoutTaxClassId['store_id'] = 1;
         $prodWithStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
-        $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $prodWithStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithNoProductTaxClass;
 
         $prodWithoutStoreIdWithTaxClassId['quote_details']['items'][] =
             $quoteDetailItemWithDefaultProductTaxClass;
         $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['tax_amount'] = 1.20;
-        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'][] =
+        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['applied_taxes'] =
+            $quoteDetailAppliedTaxesBase;
+        $prodWithoutStoreIdWithTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithDefaultProductTaxClass;
 
         $prodWithoutStoreIdWithoutTaxClassId['quote_details']['items'][] = $prodQuoteDetailItemBase;
-        $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'][] =
+        $prodWithoutStoreIdWithoutTaxClassId['expected_tax_details']['items'] =
             $prodExpectedItemWithNoProductTaxClass;
 
         return [
@@ -700,17 +948,46 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $oneProductResults = [
             'subtotal' => 10,
             'tax_amount' => 0.75,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 0.75,
+                    'percent' => 7.5,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                            'percent' => 7.5,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => 0.75,
                     'price' => 1,
                     'price_incl_tax' => 1.08,
                     'row_total' => 10,
-                    'taxable_amount' => 10,
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 10.75,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => 0.75,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 0.75,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -727,17 +1004,46 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $oneProductInclTaxResults = [
             'subtotal' => 9.3,
             'tax_amount' => 0.7,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 0.7,
+                    'percent' => 7.5,
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                    'rates' => [
+                        [
+                            'percent' => 7.5,
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                        ],
+                    ],
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => .7,
                     'price' => 0.93,
                     'price_incl_tax' => 1.0,
                     'row_total' => 9.3,
-                    'taxable_amount' => 10,  // Shouldn't this be 9.3?
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 10,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => .7,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 0.7,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -754,17 +1060,46 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $oneProductInclTaxDiffRateResults = [
             'subtotal' => 2.73,
             'tax_amount' => 0.6,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 0.6,
+                    'percent' => 22,
+                    'rates' => [
+                        [
+                            'percent' => 22,
+                            'code' => 'US - 42 - 22',
+                            'title' => 'US - 42 - 22',
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 22',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => 0.6,
                     'price' => 0.3,
                     'price_incl_tax' => 0.37,
                     'row_total' => 2.73,
-                    'taxable_amount' => 3.33, // Shouldn't this match row_total?
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 3.33,
                     'type' => 'product',
                     'tax_percent' => 22.0,
-                    'row_tax' => 0.6,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 22' => [
+                            'amount' => 0.6,
+                            'percent' => 22,
+                            'tax_rate_key' => 'US - 42 - 22',
+                            'rates' => [
+                                'US - 42 - 22' => [
+                                    'percent' => 22,
+                                    'code' => 'US - 42 - 22',
+                                    'title' => 'US - 42 - 22',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -789,27 +1124,71 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $twoProductsResults = [
             'subtotal' => 230,
             'tax_amount' => 17.25,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 17.25,
+                    'percent' => 7.5,
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                    'rates' => [
+                        [
+                            'percent' => 7.5,
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                        ],
+                    ],
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => .75,
                     'price' => 1,
                     'price_incl_tax' => 1.08,
                     'row_total' => 10,
-                    'taxable_amount' => 10,
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 10.75,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => .75,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 0.75,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
-                [
+                'sku_2' => [
+                    'code' => 'sku_2',
+                    'row_tax' => 16.5,
                     'price' => 11,
                     'price_incl_tax' => 11.83,
                     'row_total' => 220,
-                    'taxable_amount' => 220,
-                    'code' => 'sku_2',
+                    'row_total_incl_tax' => 236.5,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => 16.5,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 16.5,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -836,27 +1215,71 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $twoProductInclTaxResults = [
             'subtotal' => 232.19,
             'tax_amount' => 17.41,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
+                    'amount' => 17.41,
+                    'percent' => 7.5,
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                    'rates' => [
+                        [
+                            'percent' => 7.5,
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                        ],
+                    ],
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => .68,
                     'price' => 0.91,
                     'price_incl_tax' => 0.98,
                     'row_total' => 9.12,
-                    'taxable_amount' => 9.8,  // Shouldn't this match row_total?
-                    'code' => 'sku_1',
+                    'row_total_incl_tax' => 9.8,
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => .68,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 0.68,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
-                [
+                'sku_2' => [
+                    'code' => 'sku_2',
+                    'row_tax' => 16.73,
                     'price' => 11.15,
                     'price_incl_tax' => 11.99,
                     'row_total' => 223.07,
-                    'taxable_amount' => 239.8, // Shouldn't this be 223.07?
-                    'code' => 'sku_2',
+                    'row_total_incl_tax' => 239.8, // Shouldn't this be 223.07?
                     'type' => 'product',
                     'tax_percent' => 7.5,
-                    'row_tax' => 16.73,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 16.73,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
                 ],
             ],
         ];
@@ -890,16 +1313,92 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         $oneProductWithChildrenResults = [
             'subtotal' => 286.6,
             'tax_amount' => 27.27,
-            'discount_amount' => 0,
-            'items' => [
+            'discount_tax_compensation_amount' => 0,
+            'applied_taxes' => [
                 [
-                    'code' => 'parent_sku',
+                    'amount' => 18.51,
+                    'percent' => 7.5,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 7.5',
+                            'title' => 'US - 42 - 7.5',
+                            'percent' => 7.5,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 7.5',
+                ],
+                [
+                    'amount' => 8.76,
+                    'percent' => 22,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 22',
+                            'title' => 'US - 42 - 22',
+                            'percent' => 22,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 22',
+                ],
+            ],
+            'items' => [
+                'child_1_sku' => [
+                    'code' => 'child_1_sku',
+                    'row_tax' => 18.51,
+                    'price' => 12.34,
+                    'price_incl_tax' => 13.27,
+                    'row_total' => 246.8,
+                    'row_total_incl_tax' => 265.31,
+                    'type' => 'product',
+                    'tax_percent' => 7.5,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 7.5' => [
+                            'amount' => 18.51,
+                            'percent' => 7.5,
+                            'tax_rate_key' => 'US - 42 - 7.5',
+                            'rates' => [
+                                'US - 42 - 7.5' => [
+                                    'percent' => 7.5,
+                                    'code' => 'US - 42 - 7.5',
+                                    'title' => 'US - 42 - 7.5',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                'child_2_sku' => [
+                    'code' => 'child_2_sku',
+                    'row_tax' => 8.76,
+                    'price' => 1.99,
+                    'price_incl_tax' => 2.43,
+                    'row_total' => 39.8,
+                    'row_total_incl_tax' => 48.56,
+                    'type' => 'product',
+                    'tax_percent' => 22,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 22' => [
+                            'amount' => 8.76,
+                            'percent' => 22,
+                            'tax_rate_key' => 'US - 42 - 22',
+                            'rates' => [
+                                'US - 42 - 22' => [
+                                    'percent' => 22,
+                                    'code' => 'US - 42 - 22',
+                                    'title' => 'US - 42 - 22',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                'parent_sku' => [
                     'price' => 28.66,
                     'price_incl_tax' => 31.39,
                     'row_total' => 286.6,
-                    'taxable_amount' => 286.6,
-                    'type' => 'product',
+                    'row_total_incl_tax' => 313.87,
                     'row_tax' => 27.27,
+                    'code' => 'parent_sku',
+                    'type' => 'product',
                 ],
             ],
         ];
@@ -932,6 +1431,344 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
+
+    /**
+     * Create quote details for use with multi rules tests
+     *
+     * @return array
+     */
+    protected function setupMultiRuleQuote()
+    {
+        $baseQuote = $this->getBaseQuoteData();
+
+        $baseQuote['items'][] = [
+            'code' => 'sku_1',
+            'type' => 'product',
+            'quantity' => 10,
+            'unit_price' => 1.89,
+            'tax_class_id' => 'MultipleRulesProductClass',
+            'tax_included' => true,
+            'discount_amount' => 5,
+        ];
+        $baseQuote['items'][] = [
+            'code' => 'sku_2',
+            'type' => 'product',
+            'quantity' => 5,
+            'unit_price' => 14.99,
+            'tax_class_id' => 'MultipleRulesProductClass',
+            'tax_included' => true,
+            'discount_amount' => 10,
+        ];
+        $baseQuote['items'][] = [
+            'code' => 'sku_3',
+            'type' => 'product',
+            'quantity' => 1,
+            'unit_price' => 99.99,
+            'tax_class_id' => 'MultipleRulesProductClass',
+            'tax_included' => false,
+            'discount_amount' => 5,
+        ];
+
+        return $baseQuote;
+    }
+
+    /**
+     * Create the base results for the the multi rules test
+     *
+     * @return array
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function getBaseQuoteResult()
+    {
+        $result = [
+            'subtotal' => 183.75,
+            'tax_amount' => 42.88,
+            'discount_tax_compensation_amount' => 3.08,
+            'applied_taxes' => [
+                [
+                    'amount' => 22.1,
+                    'percent' => 13.25,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 8.25',
+                            'title' => 'US - 42 - 8.25',
+                            'percent' => 8.25,
+                        ],
+                        [
+                            'code' => 'US - 42 - 5 - 55555',
+                            'title' => 'US - 42 - 5 - 55555',
+                            'percent' => 5,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
+                ],
+                [
+                    'amount' => 20.78,
+                    'percent' => 12.4575,
+                    'rates' => [
+                        [
+                            'code' => 'US - 42 - 11 - 55555',
+                            'title' => 'US - 42 - 11 - 55555',
+                            'percent' => 11,
+                        ],
+                    ],
+                    'tax_rate_key' => 'US - 42 - 11 - 55555',
+                ],
+            ],
+            'items' => [
+                'sku_1' => [
+                    'code' => 'sku_1',
+                    'row_tax' => 3.31,
+                    'price' => 1.69,
+                    'price_incl_tax' => 2.12,
+                    'row_total' => 16.86,
+                    'row_total_incl_tax' => 21.2,
+                    'type' => 'product',
+                    'tax_percent' => 25.7075,
+                    'discount_tax_compensation_amount' => 1.03,
+                    'applied_taxes' => [
+                        'US - 42 - 8.25US - 42 - 5 - 55555' => [
+                            'amount' => 1.71,
+                            'percent' => 13.25,
+                            'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
+                            'rates' => [
+                                'US - 42 - 8.25' => [
+                                    'percent' => 8.25,
+                                    'code' => 'US - 42 - 8.25',
+                                    'title' => 'US - 42 - 8.25',
+                                ],
+                                'US - 42 - 5 - 55555' => [
+                                    'percent' => 5,
+                                    'code' => 'US - 42 - 5 - 55555',
+                                    'title' => 'US - 42 - 5 - 55555',
+                                ],
+                            ],
+                        ],
+                        'US - 42 - 11 - 55555' => [
+                            'amount' => 1.6,
+                            'percent' => 12.4575,
+                            'tax_rate_key' => 'US - 42 - 11 - 55555',
+                            'rates' => [
+                                'US - 42 - 11 - 55555' => [
+                                    'percent' => 11,
+                                    'code' => 'US - 42 - 11 - 55555',
+                                    'title' => 'US - 42 - 11 - 55555',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                'sku_2' => [
+                    'code' => 'sku_2',
+                    'row_tax' => 15.15,
+                    'price' => 13.38,
+                    'price_incl_tax' => 16.82,
+                    'row_total' => 66.9,
+                    'row_total_incl_tax' => 84.1,
+                    'type' => 'product',
+                    'tax_percent' => 25.7075,
+                    'discount_tax_compensation_amount' => 2.05,
+                    'applied_taxes' => [
+                        'US - 42 - 8.25US - 42 - 5 - 55555' => [
+                            'amount' => 7.8,
+                            'percent' => 13.25,
+                            'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
+                            'rates' => [
+                                'US - 42 - 8.25' => [
+                                    'percent' => 8.25,
+                                    'code' => 'US - 42 - 8.25',
+                                    'title' => 'US - 42 - 8.25',
+                                ],
+                                'US - 42 - 5 - 55555' => [
+                                    'percent' => 5,
+                                    'code' => 'US - 42 - 5 - 55555',
+                                    'title' => 'US - 42 - 5 - 55555',
+                                ],
+                            ],
+                        ],
+                        'US - 42 - 11 - 55555' => [
+                            'amount' => 7.35,
+                            'percent' => 12.4575,
+                            'tax_rate_key' => 'US - 42 - 11 - 55555',
+                            'rates' => [
+                                'US - 42 - 11 - 55555' => [
+                                    'percent' => 11,
+                                    'code' => 'US - 42 - 11 - 55555',
+                                    'title' => 'US - 42 - 11 - 55555',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+                'sku_3' => [
+                    'code' => 'sku_3',
+                    'row_tax' => 24.42,
+                    'price' => 99.99,
+                    'price_incl_tax' => 125.7,
+                    'row_total' => 99.99,
+                    'row_total_incl_tax' => 125.7,
+                    'type' => 'product',
+                    'tax_percent' => 25.7075,
+                    'discount_tax_compensation_amount' => 0,
+                    'applied_taxes' => [
+                        'US - 42 - 8.25US - 42 - 5 - 55555' => [
+                            'amount' => 12.59,
+                            'percent' => 13.25,
+                            'tax_rate_key' => 'US - 42 - 8.25US - 42 - 5 - 55555',
+                            'rates' => [
+                                'US - 42 - 8.25' => [
+                                    'percent' => 8.25,
+                                    'code' => 'US - 42 - 8.25',
+                                    'title' => 'US - 42 - 8.25',
+                                ],
+                                'US - 42 - 5 - 55555' => [
+                                    'percent' => 5,
+                                    'code' => 'US - 42 - 5 - 55555',
+                                    'title' => 'US - 42 - 5 - 55555',
+                                ],
+                            ],
+                        ],
+                        'US - 42 - 11 - 55555' => [
+                            'amount' => 11.83,
+                            'percent' => 12.4575,
+                            'tax_rate_key' => 'US - 42 - 11 - 55555',
+                            'rates' => [
+                                'US - 42 - 11 - 55555' => [
+                                    'percent' => 11,
+                                    'code' => 'US - 42 - 11 - 55555',
+                                    'title' => 'US - 42 - 11 - 55555',
+                                ],
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ];
+
+        return $result;
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @dataProvider multiRulesRowBasedDataProvider
+     * @magentoConfigFixture default_store tax/calculation/algorithm ROW_BASE_CALCULATION
+     */
+    public function testMultiRulesRowBased($quoteDetailsData, $expectedTaxDetails)
+    {
+        $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
+
+        $quoteDetails = $this->quoteDetailsBuilder->populateWithArray($quoteDetailsData)->create();
+
+        $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
+
+        $this->assertEquals($expectedTaxDetails, $taxDetails->__toArray());
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function multiRulesRowBasedDataProvider()
+    {
+        $quoteDetails = $this->setupMultiRuleQuote();
+
+        $results = $this->getBaseQuoteResult();
+
+        return [
+            'multi rules, multi rows' => [
+                'quote_details' => $quoteDetails,
+                'expected_tax_details' => $results,
+            ],
+        ];
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @dataProvider multiRulesTotalBasedDataProvider
+     * @magentoConfigFixture default_store tax/calculation/algorithm TOTAL_BASE_CALCULATION
+     */
+    public function testMultiRulesTotalBased($quoteDetailsData, $expectedTaxDetails)
+    {
+        $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
+
+        $quoteDetails = $this->quoteDetailsBuilder->populateWithArray($quoteDetailsData)->create();
+
+        $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
+
+        $this->assertEquals($expectedTaxDetails, $taxDetails->__toArray());
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function multiRulesTotalBasedDataProvider()
+    {
+        $quoteDetails = $this->setupMultiRuleQuote();
+
+        $results = $this->getBaseQuoteResult();
+
+        //Differences from the row base result
+        $results['subtotal'] = 183.76;
+        $results['tax_amount'] = 42.89;
+        $results['discount_tax_compensation_amount'] = 3.06;
+        $results['applied_taxes'][0]['amount'] = 22.11;
+        $results['items']['sku_2']['row_tax'] = 15.16;
+        $results['items']['sku_2']['row_total'] = 66.91;
+        $results['items']['sku_2']['discount_tax_compensation_amount'] = 2.03;
+        $results['items']['sku_2']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 7.81;
+
+        return [
+            'multi rules, multi rows' => [
+                'quote_details' => $quoteDetails,
+                'expected_tax_details' => $results,
+            ],
+        ];
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @dataProvider multiRulesUnitBasedDataProvider
+     * @magentoConfigFixture default_store tax/calculation/algorithm UNIT_BASE_CALCULATION
+     */
+    public function testMultiRulesUnitBased($quoteDetailsData, $expectedTaxDetails)
+    {
+        $quoteDetailsData = $this->performTaxClassSubstitution($quoteDetailsData);
+
+        $quoteDetails = $this->quoteDetailsBuilder->populateWithArray($quoteDetailsData)->create();
+
+        $taxDetails = $this->taxCalculationService->calculateTax($quoteDetails);
+
+        $this->assertEquals($expectedTaxDetails, $taxDetails->__toArray());
+    }
+
+    /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function multiRulesUnitBasedDataProvider()
+    {
+        $quoteDetails = $this->setupMultiRuleQuote();
+
+        $results = $this->getBaseQuoteResult();
+
+        //Differences from the row base result
+        $results['subtotal'] = 183.79;
+        $results['tax_amount'] = 42.87;
+        $results['discount_tax_compensation_amount'] = 3.05;
+        $results['applied_taxes'][1]['amount'] = 20.77;
+        $results['items']['sku_1']['row_tax'] = 3.3;
+        $results['items']['sku_1']['row_total'] = 16.9;
+        $results['items']['sku_1']['discount_tax_compensation_amount'] = 1;
+        $results['items']['sku_1']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 1.7;
+        $results['items']['sku_2']['applied_taxes']['US - 42 - 8.25US - 42 - 5 - 55555']['amount'] = 7.81;
+        $results['items']['sku_2']['applied_taxes']['US - 42 - 11 - 55555']['amount'] = 7.34;
+
+        return [
+            'multi rules, multi rows' => [
+                'quote_details' => $quoteDetails,
+                'expected_tax_details' => $results,
+            ],
+        ];
+    }
+
     /**
      * Substitutes an ID for the name of a tax class in a tax class ID field.
      *
@@ -963,6 +1800,7 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER],
             ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
             ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
+            ['name' => 'MultipleRulesProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
         ]);
 
         $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([
@@ -970,6 +1808,19 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
             ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate
         ]);
 
+        $multiTaxRates1 = $this->taxRuleFixtureFactory->createTaxRates([
+            ['percentage' => 8.25, 'country' => 'US', 'region' => 42],
+            ['percentage' => 12, 'country' => 'US', 'region' => 12], // Default store rate
+        ]);
+
+        $multiTaxRatesSamePriority = $this->taxRuleFixtureFactory->createTaxRates([
+            ['percentage' => 5, 'country' => 'US', 'region' => 42, 'postcode' => '55555'],
+        ]);
+
+        $multiTaxRatesDifferentPriority = $this->taxRuleFixtureFactory->createTaxRates([
+            ['percentage' => 11, 'country' => 'US', 'region' => 42, 'postcode' => '55555'],
+        ]);
+
         $higherRates = $this->taxRuleFixtureFactory->createTaxRates([
             ['percentage' => 22, 'country' => 'US', 'region' => 42],
             ['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate
@@ -992,10 +1843,37 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
                 'sort_order' => 0,
                 'priority' => 0,
             ],
+            [
+                'code' => 'MultiRule-1',
+                'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']],
+                'tax_rate_ids' => array_values($multiTaxRates1),
+                'sort_order' => 0,
+                'priority' => 0,
+            ],
+            [
+                'code' => 'MultiRule-2',
+                'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']],
+                'tax_rate_ids' => array_values($multiTaxRatesSamePriority),
+                'sort_order' => 0,
+                'priority' => 0,
+            ],
+            [
+                'code' => 'MultiRule-3',
+                'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                'product_tax_class_ids' => [$this->taxClasses['MultipleRulesProductClass']],
+                'tax_rate_ids' => array_values($multiTaxRatesDifferentPriority),
+                'sort_order' => 0,
+                'priority' => 1,
+            ],
         ]);
 
         // For cleanup
         $this->taxRates = array_merge($this->taxRates, $higherRates);
+        $this->taxRates = array_merge($this->taxRates, $multiTaxRates1);
+        $this->taxRates = array_merge($this->taxRates, $multiTaxRatesSamePriority);
+        $this->taxRates = array_merge($this->taxRates, $multiTaxRatesDifferentPriority);
     }
 
     /**
@@ -1009,6 +1887,8 @@ class TaxCalculationServiceTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     *
      * @return array
      */
     private function getBaseQuoteData()
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
index a16b5a05bd95d8e5a6cdac523fc1907055cb3092..594c97b52702793dc106c5d5de02a3498bf7a41f 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
@@ -26,7 +26,6 @@ namespace Magento\Tax\Service\V1;
 
 use Magento\Framework\Exception\InputException;
 use Magento\Tax\Model\ClassModel as TaxClassModel;
-use Magento\Tax\Service\V1\Data\TaxClass as TaxClassDataObject;
 use Magento\Tax\Service\V1\Data\TaxClassBuilder;
 use Magento\TestFramework\Helper\Bootstrap;
 
@@ -66,8 +65,8 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $this->taxClassBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxClassBuilder');
         $this->taxClassModel = $this->objectManager->create('Magento\Tax\Model\ClassModel');
         $this->predefinedTaxClasses = [
-            TaxClassDataObject::TYPE_PRODUCT => 'Taxable Goods',
-            TaxClassDataObject::TYPE_CUSTOMER => 'Retail Customer'
+            TaxClassServiceInterface::TYPE_PRODUCT => 'Taxable Goods',
+            TaxClassServiceInterface::TYPE_CUSTOMER => 'Retail Customer'
         ];
     }
 
@@ -80,7 +79,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     {
         $taxClassDataObject = $this->taxClassBuilder
             ->setClassName(self::SAMPLE_TAX_CLASS_NAME)
-            ->setClassType(TaxClassDataObject::TYPE_CUSTOMER)
+            ->setClassType(TaxClassServiceInterface::TYPE_CUSTOMER)
             ->create();
         $taxClassId = $this->taxClassService->createTaxClass($taxClassDataObject);
         $this->assertEquals(self::SAMPLE_TAX_CLASS_NAME, $this->taxClassModel->load($taxClassId)->getClassName());
@@ -89,7 +88,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassDataObject = $this->taxClassBuilder
             ->setClassId($taxClassId)
             ->setClassName(self::SAMPLE_TAX_CLASS_NAME . uniqid())
-            ->setClassType(TaxClassDataObject::TYPE_CUSTOMER)
+            ->setClassType(TaxClassServiceInterface::TYPE_CUSTOMER)
             ->create();
         //Should not be allowed to set the classId. Will throw InputException
         $this->taxClassService->createTaxClass($taxClassDataObject);
@@ -106,7 +105,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         //Testing against existing Tax classes which are already setup when the instance is installed
         $taxClassDataObject = $this->taxClassBuilder
             ->setClassName($this->predefinedTaxClasses[TaxClassModel::TAX_CLASS_TYPE_PRODUCT])
-            ->setClassType(TaxClassDataObject::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->create();
         $this->taxClassService->createTaxClass($taxClassDataObject);
     }
@@ -136,13 +135,13 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassName = 'Get Me';
         $taxClassDataObject = $this->taxClassBuilder
             ->setClassName($taxClassName)
-            ->setClassType(TaxClassDataObject::TYPE_CUSTOMER)
+            ->setClassType(TaxClassServiceInterface::TYPE_CUSTOMER)
             ->create();
         $taxClassId = $this->taxClassService->createTaxClass($taxClassDataObject);
         $data = $this->taxClassService->getTaxClass($taxClassId);
         $this->assertEquals($taxClassId, $data->getClassId());
         $this->assertEquals($taxClassName, $data->getClassName());
-        $this->assertEquals(TaxClassDataObject::TYPE_CUSTOMER, $data->getClassType());
+        $this->assertEquals(TaxClassServiceInterface::TYPE_CUSTOMER, $data->getClassType());
     }
 
     /**
@@ -170,14 +169,14 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         // Verify if the tax class is deleted
         $this->setExpectedException(
             'Magento\Framework\Exception\NoSuchEntityException',
-            "No such entity with taxClassId = $taxClassId"
+            "No such entity with class_id = $taxClassId"
         );
         $this->taxClassService->deleteTaxClass($taxClassId);
     }
 
     /**
      * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage No such entity with taxClassId = 99999
+     * @expectedExceptionMessage No such entity with class_id = 99999
      */
     public function testDeleteTaxClassInvalidData()
     {
@@ -222,7 +221,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
 
     /**
      * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage No such entity with taxClassId = 99999
+     * @expectedExceptionMessage No such entity with class_id = 99999
      */
     public function testUpdateTaxClassWithInvalidClassId()
     {
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
index daae33c4cbba28477c8816594b2307233903c792..77a23de151170a11c92c6f619f9c3cce5db48b68 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
@@ -28,6 +28,7 @@ use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Service\V1\Data\ZipRangeBuilder;
 use Magento\TestFramework\Helper\Bootstrap;
+use Magento\Tax\Service\V1\Data\TaxRate;
 
 class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
 {
@@ -52,11 +53,19 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
      */
     private $taxRateService;
 
+    /**
+     * Helps in creating required tax rules.
+     *
+     * @var TaxRuleFixtureFactory
+     */
+    private $taxRateFixtureFactory;
+
     protected function setUp()
     {
         $this->objectManager = Bootstrap::getObjectManager();
         $this->taxRateService = $this->objectManager->get('Magento\Tax\Service\V1\TaxRateServiceInterface');
         $this->taxRateBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxRateBuilder');
+        $this->taxRateFixtureFactory = new TaxRuleFixtureFactory();
     }
 
     /**
@@ -82,12 +91,63 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($taxData['region_id'], $taxRateServiceData->getRegionId());
         $this->assertEquals($taxData['percentage_rate'], $taxRateServiceData->getPercentageRate());
         $this->assertEquals($taxData['code'], $taxRateServiceData->getCode());
+        $this->assertEquals($taxData['percentage_rate'], $taxRateServiceData->getPercentageRate());
+        $this->assertEquals($taxData['zip_range']['from'], $taxRateServiceData->getZipRange()->getFrom());
+        $this->assertEquals($taxData['zip_range']['to'], $taxRateServiceData->getZipRange()->getTo());
+        $this->assertEquals('78765-78780', $taxRateServiceData->getPostcode());
+        $this->assertNotNull($taxRateServiceData->getId());
+    }
+
+    /**
+     * @magentoDbIsolation enabled
+     * @magentoDataFixture Magento/Store/_files/store.php
+     */
+    public function testCreateTaxRateWithTitles()
+    {
+        $store = $this->objectManager->get('\Magento\Store\Model\Store');
+        $store->load('test', 'code');
+
+        $taxData = [
+            'country_id' => 'US',
+            'region_id' => '8',
+            'percentage_rate' => '8.25',
+            'code' => 'US-CA-*-Rate' . rand(),
+            'zip_range' => ['from' => 78765, 'to' => 78780],
+            'titles' => [
+                [
+                    'store_id' => $store->getId(),
+                    'value' => 'random store title',
+                ]
+            ]
+        ];
+        // Tax rate data object created
+        $taxRate = $this->taxRateBuilder->populateWithArray($taxData)->create();
+        //Tax rate service call
+        $taxRateServiceData = $this->taxRateService->createTaxRate($taxRate);
+
+        //Assertions
+        $this->assertInstanceOf('\Magento\Tax\Service\V1\Data\TaxRate', $taxRateServiceData);
+        $this->assertEquals($taxData['country_id'], $taxRateServiceData->getCountryId());
         $this->assertEquals($taxData['region_id'], $taxRateServiceData->getRegionId());
         $this->assertEquals($taxData['percentage_rate'], $taxRateServiceData->getPercentageRate());
+        $this->assertEquals($taxData['code'], $taxRateServiceData->getCode());
+        $this->assertEquals($taxData['percentage_rate'], $taxRateServiceData->getPercentageRate());
         $this->assertEquals($taxData['zip_range']['from'], $taxRateServiceData->getZipRange()->getFrom());
         $this->assertEquals($taxData['zip_range']['to'], $taxRateServiceData->getZipRange()->getTo());
         $this->assertEquals('78765-78780', $taxRateServiceData->getPostcode());
         $this->assertNotNull($taxRateServiceData->getId());
+
+        $titles = $taxRateServiceData->getTitles();
+        $this->assertEquals(1, count($titles));
+        $this->assertEquals($store->getId(), $titles[0]->getStoreId());
+        $this->assertEquals($taxData['titles'][0]['value'], $titles[0]->getValue());
+
+        $taxRateServiceData = $this->taxRateService->getTaxRate($taxRateServiceData->getId());
+
+        $titles = $taxRateServiceData->getTitles();
+        $this->assertEquals(1, count($titles));
+        $this->assertEquals($store->getId(), $titles[0]->getStoreId());
+        $this->assertEquals($taxData['titles'][0]['value'], $titles[0]->getValue());
     }
 
     /**
@@ -123,7 +183,6 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
     {
         $expectedErrorMessages = [
             'country_id is a required field.',
-            'region_id is a required field.',
             'percentage_rate is a required field.',
             'code is a required field.'
         ];
@@ -258,12 +317,11 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
     /**
      * @magentoDbIsolation enabled
      * @expectedException \Magento\Framework\Exception\InputException
-     * @expectedExceptionMessage postcode
+     * @expectedExceptionMessage country_id
      */
     public function testUpdateTaxRateMissingRequiredFields()
     {
         $taxRate = $this->taxRateBuilder
-            ->setCountryId('US')
             ->setRegionId(42)
             ->setPercentageRate(8.25)
             ->setCode('UpdateTaxRates')
@@ -342,4 +400,91 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
             $this->fail('Caught unexpected exception');
         }
     }
+
+    /**
+     *
+     * @param \Magento\Framework\Service\V1\Data\Filter[] $filters
+     * @param \Magento\Framework\Service\V1\Data\Filter[] $filterGroup
+     * @param $expectedRateCodes
+     *
+     * @magentoDbIsolation enabled
+     * @dataProvider searchTaxRatesDataProvider
+     */
+    public function testSearchTaxRates($filters, $filterGroup, $expectedRateCodes)
+    {
+        $taxRates = $this->taxRateFixtureFactory->createTaxRates(
+            [
+                ['percentage' => 7.5, 'country' => 'US', 'region' => '42'],
+                ['percentage' => 7.5, 'country' => 'US', 'region' => '12'],
+                ['percentage' => 22.0, 'country' => 'US', 'region' => '42'],
+                ['percentage' => 10.0, 'country' => 'US', 'region' => '12']
+            ]
+        );
+
+        /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchBuilder */
+        $searchBuilder = Bootstrap::getObjectManager()
+            ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder');
+        foreach ($filters as $filter) {
+            $searchBuilder->addFilter([$filter]);
+        }
+        if (!is_null($filterGroup)) {
+            $searchBuilder->addFilter($filterGroup);
+        }
+        $searchCriteria = $searchBuilder->create();
+
+        $searchResults = $this->taxRateService->searchTaxRates($searchCriteria);
+
+        $items = [];
+        foreach ($expectedRateCodes as $rateCode) {
+            $rateId = $taxRates[$rateCode];
+            $items[] = $this->taxRateService->getTaxRate($rateId);
+        }
+
+        $resultsBuilder = Bootstrap::getObjectManager()
+            ->create('Magento\Tax\Service\V1\Data\TaxRateSearchResultsBuilder');
+        $expectedResult = $resultsBuilder->setItems($items)
+            ->setTotalCount(count($items))
+            ->setSearchCriteria($searchCriteria)
+            ->create();
+
+        $this->assertEquals($expectedResult, $searchResults);
+    }
+
+    public function searchTaxRatesDataProvider()
+    {
+        $filterBuilder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
+
+        return [
+            'eq' => [
+                [$filterBuilder->setField(TaxRate::KEY_REGION_ID)->setValue(42)->create()],
+                null,
+                ['US - 42 - 7.5', 'US - 42 - 22']
+            ],
+            'and' => [
+                [
+                    $filterBuilder->setField(TaxRate::KEY_REGION_ID)->setValue(42)->create(),
+                    $filterBuilder->setField(TaxRate::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
+                ],
+                [],
+                ['US - 42 - 22']
+            ],
+            'or' => [
+                [],
+                [
+                    $filterBuilder->setField(TaxRate::KEY_PERCENTAGE_RATE)->setValue(22.0)->create(),
+                    $filterBuilder->setField(TaxRate::KEY_PERCENTAGE_RATE)->setValue(10.0)->create(),
+                ],
+                ['US - 42 - 22', 'US - 12 - 10']
+            ],
+            'like' => [
+                [
+                    $filterBuilder->setField(TaxRate::KEY_CODE)->setValue('%7.5')->setConditionType('like')
+                        ->create()
+                ],
+                [],
+                ['US - 42 - 7.5', 'US - 12 - 7.5']
+            ]
+        ];
+    }
+
 }
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleFixtureFactory.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleFixtureFactory.php
index 38dd7faea4111dc6b60cc3fa91389b20b1465398..05bc7949f68e99591537ab4c1d3a5eb5bfb14dc6 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleFixtureFactory.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleFixtureFactory.php
@@ -99,9 +99,14 @@ class TaxRuleFixtureFactory
         $rates = [];
         foreach ($ratesData as $rateData) {
             $code = "{$rateData['country']} - {$rateData['region']} - {$rateData['percentage']}";
+            $postcode = '*';
+            if (isset($rateData['postcode'])) {
+                $postcode = $rateData['postcode'];
+                $code = $code . " - " . $postcode;
+            }
             $taxRateBuilder->setCountryId($rateData['country'])
                 ->setRegionId($rateData['region'])
-                ->setPostcode('*')
+                ->setPostcode($postcode)
                 ->setCode($code)
                 ->setPercentageRate($rateData['percentage']);
 
diff --git a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
index 462b8a7fd567b361a9800639a9a5f3fea039a1f0..2e6af1e6a42ec127f97a85a86803889deb620fb7 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
@@ -24,10 +24,12 @@
 
 namespace Magento\Tax\Service\V1;
 
-use Magento\TestFramework\Helper\Bootstrap;
-use Magento\Tax\Service\V1\Data\TaxRule;
 use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Framework\Exception\InputException;
+use Magento\Tax\Service\V1\Data\TaxRule;
+use Magento\Tax\Model\ClassModel;
+use Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder;
+use Magento\TestFramework\Helper\Bootstrap;
 
 /**
  * Class TaxRuleServiceTest tests Magento/Tax/Service/V1/TaxRuleService
@@ -56,11 +58,46 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
      */
     private $taxRuleService;
 
+    /**
+     * Helps in creating required tax rules.
+     *
+     * @var TaxRuleFixtureFactory
+     */
+    private $taxRuleFixtureFactory;
+
+    /**
+     * Array of default tax classes ids
+     *
+     * Key is class name
+     *
+     * @var int[]
+     */
+    private $taxClasses;
+
+    /**
+     * Array of default tax rates ids.
+     *
+     * Key is rate percentage as string.
+     *
+     * @var int[]
+     */
+    private $taxRates;
+
+    /**
+     * Array of default tax rules ids.
+     *
+     * Key is rule code.
+     *
+     * @var int[]
+     */
+    private $taxRules;
+
     protected function setUp()
     {
         $this->objectManager = Bootstrap::getObjectManager();
         $this->taxRuleService = $this->objectManager->get('Magento\Tax\Service\V1\TaxRuleServiceInterface');
         $this->taxRuleBuilder = $this->objectManager->create('Magento\Tax\Service\V1\Data\TaxRuleBuilder');
+        $this->taxRuleFixtureFactory = new TaxRuleFixtureFactory();
     }
 
     /**
@@ -260,6 +297,150 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
         $this->taxRuleService->updateTaxRule($updatedTaxRule);
     }
 
+    /**
+     *
+     * @param Filter[] $filters
+     * @param Filter[] $filterGroup
+     * @param string[] $expectedResultCodes The codes of the tax rules that are expected to be found
+     *
+     * @magentoDbIsolation enabled
+     * @dataProvider searchTaxRulesDataProvider
+     */
+    public function testSearchTaxRules($filters, $filterGroup, $expectedRuleCodes)
+    {
+        $this->setUpDefaultRules();
+
+        /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchBuilder */
+        $searchBuilder = Bootstrap::getObjectManager()
+            ->create('Magento\Framework\Service\V1\Data\SearchCriteriaBuilder');
+        foreach ($filters as $filter) {
+            $searchBuilder->addFilter([$filter]);
+        }
+        if (!is_null($filterGroup)) {
+            $searchBuilder->addFilter($filterGroup);
+        }
+        $searchCriteria = $searchBuilder->create();
+
+        $searchResults = $this->taxRuleService->searchTaxRules($searchCriteria);
+        $items = [];
+        foreach ($expectedRuleCodes as $ruleCode) {
+            $ruleId = $this->taxRules[$ruleCode];
+            $items[] = $this->taxRuleService->getTaxRule($ruleId);
+        }
+
+        /** @var TaxRuleSearchResultsBuilder $resultsBuilder */
+        $resultsBuilder = Bootstrap::getObjectManager()
+            ->create('Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder');
+        $expectedResult = $resultsBuilder->setItems($items)
+            ->setTotalCount(count($items))
+            ->setSearchCriteria($searchCriteria)
+            ->create();
+        $this->assertEquals($expectedResult, $searchResults);
+        $this->tearDownDefaultRules();
+    }
+
+    public function searchTaxRulesDataProvider()
+    {
+        $filterBuilder = Bootstrap::getObjectManager()->create('\Magento\Framework\Service\V1\Data\FilterBuilder');
+
+        return [
+            'code eq "Default Rule"' => [
+                [$filterBuilder->setField(TaxRule::CODE)->setValue('Default Rule')->create()],
+                null,
+                ['Default Rule']
+            ],
+            'sort_order eq 0 AND priority eq 0' => [
+                [
+                    $filterBuilder->setField(TaxRule::SORT_ORDER)->setValue('0')->create(),
+                    $filterBuilder->setField(TaxRule::PRIORITY)->setValue('0')->create(),
+                ],
+                [],
+                ['Default Rule', 'Higher Rate Rule']
+            ],
+            'code eq "Default Rule" OR code eq "Higher Rate Rule"' => [
+                [],
+                [
+                    $filterBuilder->setField(TaxRule::CODE)->setValue('Default Rule')->create(),
+                    $filterBuilder->setField(TaxRule::CODE)->setValue('Higher Rate Rule')->create(),
+                ],
+                ['Default Rule', 'Higher Rate Rule']
+            ],
+            'code like "%Rule"' => [
+                [
+                    $filterBuilder->setField(TaxRule::CODE)->setValue('%Rule')->setConditionType('like')
+                        ->create()
+                ],
+                [],
+                ['Default Rule', 'Higher Rate Rule']
+            ],
+        ];
+    }
+
+    /**
+     * Helper function that sets up some default rules
+     */
+    private function setUpDefaultRules()
+    {
+        $this->taxClasses = $this->taxRuleFixtureFactory->createTaxClasses([
+                ['name' => 'DefaultCustomerClass', 'type' => ClassModel::TAX_CLASS_TYPE_CUSTOMER],
+                ['name' => 'DefaultProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
+                ['name' => 'HigherProductClass', 'type' => ClassModel::TAX_CLASS_TYPE_PRODUCT],
+            ]);
+
+        $this->taxRates = $this->taxRuleFixtureFactory->createTaxRates([
+                ['percentage' => 7.5, 'country' => 'US', 'region' => 42],
+                ['percentage' => 7.5, 'country' => 'US', 'region' => 12], // Default store rate
+            ]);
+
+        $higherRates = $this->taxRuleFixtureFactory->createTaxRates([
+                ['percentage' => 22, 'country' => 'US', 'region' => 42],
+                ['percentage' => 10, 'country' => 'US', 'region' => 12], // Default store rate
+            ]);
+
+        $this->taxRules = $this->taxRuleFixtureFactory->createTaxRules([
+                [
+                    'code' => 'Default Rule',
+                    'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                    'product_tax_class_ids' => [$this->taxClasses['DefaultProductClass']],
+                    'tax_rate_ids' => array_values($this->taxRates),
+                    'sort_order' => 0,
+                    'priority' => 0,
+                    'calculate_subtotal' => 1,
+                ],
+                [
+                    'code' => 'Higher Rate Rule',
+                    'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                    'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']],
+                    'tax_rate_ids' => array_values($higherRates),
+                    'sort_order' => 0,
+                    'priority' => 0,
+                    'calculate_subtotal' => 1,
+                ],
+                [
+                    'code' => 'Highest Rate',
+                    'customer_tax_class_ids' => [$this->taxClasses['DefaultCustomerClass'], 3],
+                    'product_tax_class_ids' => [$this->taxClasses['HigherProductClass']],
+                    'tax_rate_ids' => array_values($higherRates),
+                    'sort_order' => 1,
+                    'priority' => 1,
+                    'calculate_subtotal' => 0,
+                ],
+            ]);
+
+        // For cleanup
+        $this->taxRates = array_merge($this->taxRates, $higherRates);
+    }
+
+    /**
+     * Helper function that tears down some default rules
+     */
+    private function tearDownDefaultRules()
+    {
+        $this->taxRuleFixtureFactory->deleteTaxRules(array_values($this->taxRules));
+        $this->taxRuleFixtureFactory->deleteTaxRates(array_values($this->taxRates));
+        $this->taxRuleFixtureFactory->deleteTaxClasses(array_values($this->taxClasses));
+    }
+
     /**
      * Creates Tax Rule Data Object
      *
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php
index 5a25277044d95b7293bbb47368f0a1cad383b982..1bcd2a2255e0df9867e0c9df916da791484d101f 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_after_discount.php
@@ -81,8 +81,6 @@ $taxCalculationData['excluding_tax_apply_tax_after_discount'] = [
             'base_shipping_amount' => 10,
             'shipping_incl_tax' => 10.75,
             'base_shipping_incl_tax' => 10.75,
-            'shipping_taxable' => 10,
-            'base_shipping_taxable' => 10,
             'shipping_tax_amount' => 0.75,
             'base_shipping_tax_amount' => 0.75,
             'discount_amount' => -10,
@@ -124,8 +122,6 @@ $taxCalculationData['excluding_tax_apply_tax_after_discount'] = [
             'simple1' => [
                 'row_total' => 20,
                 'base_row_total' => 20,
-                'taxable_amount' => 20,
-                'base_taxable_amount' => 20,
                 'tax_percent' => 20,
                 'price' => 10,
                 'base_price' => 10,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php
index 845791b66daef5fda469df55323cddd31a5c0cdd..9e593855d6d04f453fa1b6080f59c296a1c58661 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_apply_tax_before_discount.php
@@ -70,8 +70,6 @@ $taxCalculationData['excluding_tax_apply_tax_before_discount'] = [
             'base_shipping_amount' => 10,
             'shipping_incl_tax' => 12,
             'base_shipping_incl_tax' => 12,
-            'shipping_taxable' => 10,
-            'base_shipping_taxable' => 10,
             'shipping_tax_amount' => 2,
             'base_shipping_tax_amount' => 2,
             'discount_amount' => -10,
@@ -87,8 +85,6 @@ $taxCalculationData['excluding_tax_apply_tax_before_discount'] = [
             'simple1' => [
                 'row_total' => 20,
                 'base_row_total' => 20,
-                'taxable_amount' => 20,
-                'base_taxable_amount' => 20,
                 'tax_percent' => 20,
                 'price' => 10,
                 'base_price' => 10,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php
index 07c050f2ecf205973623a1d4d694126507bb57d4..e7374e25076368fd837c2a3d5c436449addc2742 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_row.php
@@ -89,8 +89,6 @@ $taxCalculationData['excluding_tax__multi_item_row'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
@@ -109,8 +107,6 @@ $taxCalculationData['excluding_tax__multi_item_row'] = [
             'simple2' => [
                 'row_total' => 11,
                 'base_row_total' => 11,
-                'taxable_amount' => 11,
-                'base_taxable_amount' => 11,
                 'tax_percent' => 8.25,
                 'price' => 11,
                 'base_price' => 11,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php
index cacf6059a5d338b3ccbdfa7b9635a162ebc626fc..21ef5496877af34c68ccc09a47210fabc84bae56 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_total.php
@@ -89,8 +89,6 @@ $taxCalculationData['excluding_tax__multi_item_total'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
@@ -109,8 +107,6 @@ $taxCalculationData['excluding_tax__multi_item_total'] = [
             'simple2' => [
                 'row_total' => 11,
                 'base_row_total' => 11,
-                'taxable_amount' => 11,
-                'base_taxable_amount' => 11,
                 'tax_percent' => 8.25,
                 'price' => 11,
                 'base_price' => 11,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php
index 9f0a90aed5c3c77bd3c45051d362135130e1168e..269d62c08e9d553b48157e65e299b869362789c4 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_multi_item_unit.php
@@ -89,8 +89,6 @@ $taxCalculationData['excluding_tax__multi_item_unit'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
@@ -109,8 +107,6 @@ $taxCalculationData['excluding_tax__multi_item_unit'] = [
             'simple2' => [
                 'row_total' => 11,
                 'base_row_total' => 11,
-                'taxable_amount' => 11,
-                'base_taxable_amount' => 11,
                 'tax_percent' => 8.25,
                 'price' => 11,
                 'base_price' => 11,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php
index 2ab70e7f36b245542fbb336ed0ba56249158c36c..e9756a1cc51d1e0885eba8533936050443311533 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_row.php
@@ -82,8 +82,6 @@ $taxCalculationData['excluding_tax_row'] = [
             'simple1' => [
                 'row_total' => 20,
                 'base_row_total' => 20,
-                'taxable_amount' => 20,
-                'base_taxable_amount' => 20,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php
index 73befba2bdc84ef2fc65237bd5d4f17961e4d3da..83e19c16015a8a6722bfca9f396cab65f60be942 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_total.php
@@ -82,8 +82,6 @@ $taxCalculationData['excluding_tax_total'] = [
             'simple1' => [
                 'row_total' => 20,
                 'base_row_total' => 20,
-                'taxable_amount' => 20,
-                'base_taxable_amount' => 20,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php
index 2e64a8a5b5c53a1f1747d4c604df983605504f2b..31cc9c16906f351aae2bc9aa9d645ab34abe7c91 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/excluding_tax_unit.php
@@ -82,8 +82,6 @@ $taxCalculationData['excluding_tax_unit'] = [
             'simple1' => [
                 'row_total' => 20,
                 'base_row_total' => 20,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 8.25,
                 'price' => 10,
                 'base_price' => 10,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_disabled.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_disabled.php
index f79dafa544da808a520f4f4108b62d448fdcfc25..c868acbe10b55b03a09480c2365fd85bef9995a0 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_disabled.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_disabled.php
@@ -85,8 +85,6 @@ $taxCalculationData['including_tax_cross_border_trade_disabled'] = [
             'simple1' => [
                 'row_total' => 18.16,
                 'base_row_total' => 18.16,
-                'taxable_amount' => 10.90,
-                'base_taxable_amount' => 10.90,
                 'tax_percent' => 20,
                 'price' => 9.08,
                 'base_price' => 9.08,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_enabled.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_enabled.php
index c1875cec5a1b265439a56fef108f6bd493b87297..6d221d48d3444467cb9011641cd63839fa0729ec 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_enabled.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_cross_border_trade_enabled.php
@@ -85,8 +85,6 @@ $taxCalculationData['including_tax_cross_border_trade_enabled'] = [
             'simple1' => [
                 'row_total' => 16.64,
                 'base_row_total' => 16.64,
-                'taxable_amount' => 9.99,
-                'base_taxable_amount' => 9.99,
                 'tax_percent' => 20,
                 'price' => 8.32,
                 'base_price' => 8.32,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php
index 65e4c3691257c4aa4ae0e8299ef953aa561c7f05..e2f45676bce3a92e7111d1ac6e240d6c785f518b 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_row.php
@@ -84,8 +84,6 @@ $taxCalculationData['including_tax_row'] = [
             'simple1' => [
                 'row_total' => 16.65,
                 'base_row_total' => 16.65,
-                'taxable_amount' => 19.98,
-                'base_taxable_amount' => 19.98,
                 'tax_percent' => 20,
                 'price' => 8.33,
                 'base_price' => 8.33,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php
index c737425c6563c54223dfe621535d5fd56624c256..e17a91e208b3ef2e6518488defe5fcfbd119cbf9 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_total.php
@@ -84,8 +84,6 @@ $taxCalculationData['including_tax_total'] = [
             'simple1' => [
                 'row_total' => 16.65,
                 'base_row_total' => 16.65,
-                'taxable_amount' => 19.98,
-                'base_taxable_amount' => 19.98,
                 'tax_percent' => 20,
                 'price' => 8.33,
                 'base_price' => 8.33,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php
index 18ec0c995ad3a7658914ac3c16e21111aeb018f5..0f91344914d735c71aba8c201d038029e3f8af7e 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/including_tax_unit.php
@@ -84,8 +84,6 @@ $taxCalculationData['including_tax_unit'] = [
             'simple1' => [
                 'row_total' => 16.64,
                 'base_row_total' => 16.64,
-                'taxable_amount' => 9.99,
-                'base_taxable_amount' => 9.99,
                 'tax_percent' => 20,
                 'price' => 8.32,
                 'base_price' => 8.32,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_no.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_no.php
index 6578ab2fdb1e7be7ba28bbd4c40e3e6c725465fa..6a14dee80632b349a56a1149729d0b6b60ffad3a 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_no.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_no.php
@@ -130,8 +130,6 @@ $taxCalculationData['multi_tax_rule_total_calculate_subtotal_no'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 13.4125,
                 'price' => 1,
                 'base_price' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_yes.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_yes.php
index d88e3ddb026ad453330aa320704e99dd0ea9dbe9..30f62a99ee03976a467337574e526f59d8e04b80 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_yes.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_total_calculate_subtotal_yes.php
@@ -130,8 +130,6 @@ $taxCalculationData['multi_tax_rule_total_calculate_subtotal_yes'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 10,
-                'base_taxable_amount' => 10,
                 'tax_percent' => 13,
                 'price' => 1,
                 'base_price' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php
new file mode 100644
index 0000000000000000000000000000000000000000..8b18adbb1126af1f46c2028d6ea721c80cbb952a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+/**
+ * This test case test the scenario where there are two tax rules with different priority
+ * The calculate_subtotal field is on, the second tax rate will be applied on subtotal only.
+ * This testcase uses total based calculation.
+ */
+$taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_row'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_ROW_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 9,
+            SetupUtil::TAX_RATE_AUSTIN => 5,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+            [
+                //tax rule 1 for product
+                'code' => 'Product Tax Rule TX',
+                'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1],
+                'tax_rate' => [SetupUtil::TAX_RATE_TX],
+                'priority' => 1,
+            ],
+            [
+                //tax rule 2 for product
+                'code' => 'Product Tax Rule AUSTIN',
+                'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1],
+                'tax_rate' => [SetupUtil::TAX_RATE_AUSTIN],
+                'priority' => 2,
+                'calculate_subtotal' => 1,
+            ],
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+            'tax_postcode' => SetupUtil::AUSTIN_POST_CODE,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10.05,
+                'qty' => 1,
+            ],
+            [
+                'sku' => 'simple2',
+                'price' => 10.45,
+                'qty' => 1,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20.5,
+            'base_subtotal' => 20.5,
+            'subtotal_incl_tax' => 23.36,
+            'base_subtotal_incl_tax' => 23.36,
+            'tax_amount' => 2.86,
+            'base_tax_amount' => 2.86,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 23.36,
+            'base_grand_total' => 23.36,
+            'applied_taxes' => [
+                SetupUtil::TAX_RATE_TX => [
+                    'percent' => 9,
+                    'amount' => 1.84,
+                    'base_amount' => 1.84,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_TX,
+                            'title' => SetupUtil::TAX_RATE_TX,
+                            'percent' => 9,
+                        ],
+                    ],
+                ],
+                SetupUtil::TAX_RATE_AUSTIN => [
+                    'percent' => 5,
+                    'amount' => 1.02,
+                    'base_amount' => 1.02,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_AUSTIN,
+                            'title' => SetupUtil::TAX_RATE_AUSTIN,
+                            'percent' => 5,
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 10.05,
+                'base_row_total' => 10.05,
+                'tax_percent' => 14,
+                'price' => 10.05,
+                'base_price' => 10.05,
+                'price_incl_tax' => 11.45,
+                'base_price_incl_tax' => 11.45,
+                'row_total_incl_tax' => 11.45,
+                'base_row_total_incl_tax' => 11.45,
+                'tax_amount' => 1.4,
+                'base_tax_amount' => 1.4,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+                'applied_taxes' => [
+                    [
+                        'amount' => 0.9,
+                        'base_amount' => 0.9,
+                        'percent' => 9,
+                        'id' => SetupUtil::TAX_RATE_TX,
+                        'rates' => [
+                            [
+                                'percent' => 9,
+                                'code' => SetupUtil::TAX_RATE_TX,
+                                'title' => SetupUtil::TAX_RATE_TX,
+                            ],
+                        ],
+                    ],
+                    [
+                        'amount' => 0.5,
+                        'base_amount' => 0.5,
+                        'percent' => 5,
+                        'id' => SetupUtil::TAX_RATE_AUSTIN,
+                        'rates' => [
+                            [
+                                'percent' => 5,
+                                'code' => SetupUtil::TAX_RATE_AUSTIN,
+                                'title' => SetupUtil::TAX_RATE_AUSTIN,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'simple2' => [
+                'row_total' => 10.45,
+                'base_row_total' => 10.45,
+                'tax_percent' => 14,
+                'price' => 10.45,
+                'base_price' => 10.45,
+                'price_incl_tax' => 11.91,
+                'base_price_incl_tax' => 11.91,
+                'row_total_incl_tax' => 11.91,
+                'base_row_total_incl_tax' => 11.91,
+                'tax_amount' => 1.46,
+                'base_tax_amount' => 1.46,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+                'applied_taxes' => [
+                    [
+                        'amount' => 0.94,
+                        'base_amount' => 0.94,
+                        'percent' => 9,
+                        'id' => SetupUtil::TAX_RATE_TX,
+                        'rates' => [
+                            [
+                                'percent' => 9,
+                                'code' => SetupUtil::TAX_RATE_TX,
+                                'title' => SetupUtil::TAX_RATE_TX,
+                            ],
+                        ],
+                    ],
+                    [
+                        'amount' => 0.52,
+                        'base_amount' => 0.52,
+                        'percent' => 5,
+                        'id' => SetupUtil::TAX_RATE_AUSTIN,
+                        'rates' => [
+                            [
+                                'percent' => 5,
+                                'code' => SetupUtil::TAX_RATE_AUSTIN,
+                                'title' => SetupUtil::TAX_RATE_AUSTIN,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php
new file mode 100644
index 0000000000000000000000000000000000000000..d0d85808d2cd888e87bbd9131ba0a8252c7478ba
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+use Magento\Tax\Model\Config;
+use Magento\Tax\Model\Sales\Total\Quote\SetupUtil;
+use Magento\Tax\Model\Calculation;
+
+/**
+ * This test case test the scenario where there are two tax rules with different priority
+ * The calculate_subtotal field is on, the second tax rate will be applied on subtotal only.
+ * This testcase uses total based calculation.
+ */
+$taxCalculationData['multi_tax_rule_two_row_calculate_subtotal_yes_total'] = [
+    'config_data' => [
+        SetupUtil::CONFIG_OVERRIDES => [
+            Config::CONFIG_XML_PATH_APPLY_AFTER_DISCOUNT => 1,
+            Config::XML_PATH_ALGORITHM => Calculation::CALC_TOTAL_BASE,
+        ],
+        SetupUtil::TAX_RATE_OVERRIDES => [
+            SetupUtil::TAX_RATE_TX => 9,
+            SetupUtil::TAX_RATE_AUSTIN => 5,
+        ],
+        SetupUtil::TAX_RULE_OVERRIDES => [
+            [
+                //tax rule 1 for product
+                'code' => 'Product Tax Rule TX',
+                'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1],
+                'tax_rate' => [SetupUtil::TAX_RATE_TX],
+                'priority' => 1,
+            ],
+            [
+                //tax rule 2 for product
+                'code' => 'Product Tax Rule AUSTIN',
+                'tax_product_class' => [SetupUtil::PRODUCT_TAX_CLASS_1],
+                'tax_rate' => [SetupUtil::TAX_RATE_AUSTIN],
+                'priority' => 2,
+                'calculate_subtotal' => 1,
+            ],
+        ],
+    ],
+    'quote_data' => [
+        'billing_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+        ],
+        'shipping_address' => [
+            'region_id' => SetupUtil::REGION_TX,
+            'tax_postcode' => SetupUtil::AUSTIN_POST_CODE,
+        ],
+        'items' => [
+            [
+                'sku' => 'simple1',
+                'price' => 10.05,
+                'qty' => 1,
+            ],
+            [
+                'sku' => 'simple2',
+                'price' => 10.45,
+                'qty' => 1,
+            ],
+        ],
+    ],
+    'expected_results' => [
+        'address_data' => [
+            'subtotal' => 20.5,
+            'base_subtotal' => 20.5,
+            'subtotal_incl_tax' => 23.38,
+            'base_subtotal_incl_tax' => 23.38,
+            'tax_amount' => 2.88,
+            'base_tax_amount' => 2.88,
+            'shipping_amount' => 0,
+            'base_shipping_amount' => 0,
+            'shipping_incl_tax' => 0,
+            'base_shipping_incl_tax' => 0,
+            'shipping_taxable' => 0,
+            'base_shipping_taxable' => 0,
+            'shipping_tax_amount' => 0,
+            'base_shipping_tax_amount' => 0,
+            'discount_amount' => 0,
+            'base_discount_amount' => 0,
+            'hidden_tax_amount' => 0,
+            'base_hidden_tax_amount' => 0,
+            'shipping_hidden_tax_amount' => 0,
+            'base_shipping_hidden_tax_amount' => 0,
+            'grand_total' => 23.38,
+            'base_grand_total' => 23.38,
+            'applied_taxes' => [
+                SetupUtil::TAX_RATE_TX => [
+                    'percent' => 9,
+                    'amount' => 1.85,
+                    'base_amount' => 1.85,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_TX,
+                            'title' => SetupUtil::TAX_RATE_TX,
+                            'percent' => 9,
+                        ],
+                    ],
+                ],
+                SetupUtil::TAX_RATE_AUSTIN => [
+                    'percent' => 5,
+                    'amount' => 1.03,
+                    'base_amount' => 1.03,
+                    'rates' => [
+                        [
+                            'code' => SetupUtil::TAX_RATE_AUSTIN,
+                            'title' => SetupUtil::TAX_RATE_AUSTIN,
+                            'percent' => 5,
+                        ],
+                    ],
+                ],
+            ],
+        ],
+        'items_data' => [
+            'simple1' => [
+                'row_total' => 10.05,
+                'base_row_total' => 10.05,
+                'tax_percent' => 14,
+                'price' => 10.05,
+                'base_price' => 10.05,
+                'price_incl_tax' => 11.45,
+                'base_price_incl_tax' => 11.45,
+                'row_total_incl_tax' => 11.45,
+                'base_row_total_incl_tax' => 11.45,
+                'tax_amount' => 1.40,
+                'base_tax_amount' => 1.40,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+                'applied_taxes' => [
+                    [
+                        'amount' => 0.9,
+                        'base_amount' => 0.9,
+                        'percent' => 9,
+                        'id' => SetupUtil::TAX_RATE_TX,
+                        'rates' => [
+                            [
+                                'percent' => 9,
+                                'code' => SetupUtil::TAX_RATE_TX,
+                                'title' => SetupUtil::TAX_RATE_TX,
+                            ],
+                        ],
+                    ],
+                    [
+                        'amount' => 0.5,
+                        'base_amount' => 0.5,
+                        'percent' => 5,
+                        'id' => SetupUtil::TAX_RATE_AUSTIN,
+                        'rates' => [
+                            [
+                                'code' => SetupUtil::TAX_RATE_AUSTIN,
+                                'title' => SetupUtil::TAX_RATE_AUSTIN,
+                                'percent' => 5,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+            'simple2' => [
+                'row_total' => 10.45,
+                'base_row_total' => 10.45,
+                'tax_percent' => 14,
+                'price' => 10.45,
+                'base_price' => 10.45,
+                'price_incl_tax' => 11.93,
+                'base_price_incl_tax' => 11.93,
+                'row_total_incl_tax' => 11.93,
+                'base_row_total_incl_tax' => 11.93,
+                'tax_amount' => 1.48,
+                'base_tax_amount' => 1.48,
+                'discount_amount' => 0,
+                'base_discount_amount' => 0,
+                'discount_percent' => 0,
+                'hidden_tax_amount' => 0,
+                'base_hidden_tax_amount' => 0,
+                'applied_taxes' => [
+                    [
+                        'amount' => 0.95,
+                        'base_amount' => 0.95,
+                        'percent' => 9,
+                        'id' => SetupUtil::TAX_RATE_TX,
+                        'rates' => [
+                            [
+                                'percent' => 9,
+                                'code' => SetupUtil::TAX_RATE_TX,
+                                'title' => SetupUtil::TAX_RATE_TX,
+                            ],
+                        ],
+                    ],
+                    [
+                        'amount' => 0.53,
+                        'base_amount' => 0.53,
+                        'percent' => 5,
+                        'id' => SetupUtil::TAX_RATE_AUSTIN,
+                        'rates' => [
+                            [
+                                'percent' => 5,
+                                'code' => SetupUtil::TAX_RATE_AUSTIN,
+                                'title' => SetupUtil::TAX_RATE_AUSTIN,
+                            ],
+                        ],
+                    ],
+                ],
+            ],
+        ],
+    ],
+];
\ No newline at end of file
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_no.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_no.php
index 5e0701ea3869bf151ffb4994e1a3689c4398032a..138895cf45e4849a79d88317d638a7f2b3a72ac1 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_no.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_no.php
@@ -130,8 +130,6 @@ $taxCalculationData['multi_tax_rule_unit_calculate_subtotal_no'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 1,
-                'base_taxable_amount' => 1,
                 'tax_percent' => 13.4125,
                 'price' => 1,
                 'base_price' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_yes.php b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_yes.php
index 025ba3b402f1274151f8f6d797dff97e4b381fa4..6f766547472ce75358bb6aa5c05acb85021dc1f8 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_yes.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/scenarios/multi_tax_rule_unit_calculate_subtotal_yes.php
@@ -130,8 +130,6 @@ $taxCalculationData['multi_tax_rule_unit_calculate_subtotal_yes'] = [
             'simple1' => [
                 'row_total' => 10,
                 'base_row_total' => 10,
-                'taxable_amount' => 1,
-                'base_taxable_amount' => 1,
                 'tax_percent' => 13,
                 'price' => 1,
                 'base_price' => 1,
diff --git a/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php
index b98287caeccba808e802f6a92b1c9fe92d390745..452752b9baaf076c3abfdcd39e6b2a6ec74a00fb 100644
--- a/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php
+++ b/dev/tests/integration/testsuite/Magento/Tax/_files/tax_calculation_data_aggregated.php
@@ -45,4 +45,5 @@ require_once __DIR__ . '/scenarios/including_tax_cross_border_trade_enabled.php'
 require_once __DIR__ . '/scenarios/multi_tax_rule_total_calculate_subtotal_no.php';
 require_once __DIR__ . '/scenarios/multi_tax_rule_unit_calculate_subtotal_no.php';
 require_once __DIR__ . '/scenarios/multi_tax_rule_total_calculate_subtotal_yes.php';
-require_once __DIR__ . '/scenarios/multi_tax_rule_unit_calculate_subtotal_yes.php';
+require_once __DIR__ . '/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_row.php';
+require_once __DIR__ . '/scenarios/multi_tax_rule_two_row_calculate_subtotal_yes_total.php';
diff --git a/dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Noroute.php b/dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Noroute.php
new file mode 100644
index 0000000000000000000000000000000000000000..43cbb8362f06f9dc36ff2df24ac64b98d8a5b732
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/TestFixture/Controller/Adminhtml/Noroute.php
@@ -0,0 +1,56 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\TestFixture\Controller\Adminhtml;
+
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\Action;
+use Magento\Framework\App\ResponseInterface;
+
+/**
+ * Mock index controller class
+ */
+class Noroute implements \Magento\Framework\App\ActionInterface
+{
+    /**
+     * Dispatch request
+     *
+     * @param RequestInterface $request
+     * @return ResponseInterface
+     * @throws Action\NotFoundException
+     */
+    public function dispatch(RequestInterface $request)
+    {
+
+    }
+
+    /**
+     * Get Response object
+     *
+     * @return ResponseInterface
+     */
+    public function getResponse()
+    {
+
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
index c127dc467ce698e0dfa2c566d21aace90d118de3..4076938f01ceafb24af8e68318618cb1c66490d0 100644
--- a/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
+++ b/dev/tests/integration/testsuite/Magento/Wishlist/Controller/IndexTest.php
@@ -136,7 +136,7 @@ class IndexTest extends \Magento\TestFramework\TestCase\AbstractController
     {
         $this->_objectManager->configure(
             [
-                'Magento\Wishlist\Controller\Index' => [
+                'Magento\Wishlist\Controller\Index\Send' => [
                     'arguments' => [
                         'transportBuilder' => [
                             'instance' => 'Magento\TestFramework\Mail\Template\TransportBuilderMock'
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 e96b7a1646ea444564752cf538025d8637ff5da5..7f0b60616a16406524001ce631432b4b7894ed09 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
@@ -559,7 +559,7 @@ return array(
     ),
     array(
         'Mage_Adminhtml_Model_System_Config_Source_Shipping_Taxclass',
-        'Magento\Tax\Model\Config\Source\TaxClass\Product'
+        'Magento\Tax\Model\TaxClass\Source\Product'
     ),
     array(
         'Mage_Adminhtml_Model_System_Config_Source_Storage_Media_Database',
@@ -778,7 +778,7 @@ return array(
     array('Mage_Core_Block_Template_Facade'),
     array('Mage_Core_Block_Template_Smarty'),
     array('Mage_Core_Block_Template_Zend'),
-    array('Mage_Core_Controller_Magento_Router_Admin', 'Magento\Backend\App\Router\DefaultRouter'),
+    array('Mage_Core_Controller_Magento_Router_Admin', 'Magento\Backend\App\Router'),
     array('Mage_Core_Model_Convert'),
     array('Mage_Core_Model_Config_Fieldset', 'Magento\Core\Model\Fieldset\Config'),
     array('Mage_Core_Model_Config_Options', 'Magento\Framework\App\Filesystem'),
@@ -2701,6 +2701,8 @@ return array(
         'Magento\Bundle\Pricing\Price\BasePrice',
         'Magento\Catalog\Pricing\Price\BasePrice'
     ],
+    ['Magento\Cataloginventory\Model\Resource\Indexer\Stock'],
+    ['Magento\Catalog\Model\Product\Indexer\Eav'],
     ['Magento\Bundle\Pricing\Price\BasePriceInterface'],
     ['Magento\Banner\Helper\Data'],
     ['Magento\Cms\Helper\Data'],
@@ -2714,5 +2716,13 @@ return array(
     ['Magento\Rule\Helper\Data'],
     ['Magento\Theme\Helper\Data'],
     ['Magento\Widget\Helper\Data'],
+    ['Magento\Tax\Model\Resource\Calculation\Grid\Collection'],
+    ['Magento\Tax\Model\Resource\Rule\Grid\Collection'],
+    ['Magento\Tax\Model\Resource\Rule\Grid\Options\CustomerTaxClass'],
+    ['Magento\Tax\Model\Resource\Rule\Grid\Options\HashOptimized'],
+    ['Magento\Tax\Model\Resource\Rule\Grid\Options\ProductTaxClass'],
     ['Magento\SalesArchive\Block\Adminhtml\Sales\Order\Grid\Massaction'],
+    ['Magento\Catalog\Helper\Product\Price'],
+    ['Magento\Tax\Model\Config\Source\TaxClass\Product', 'Magento\Tax\Model\TaxClass\Source\Product'],
+    ['Magento\Tax\Model\Config\Source\TaxClass\Customer', 'Magento\Tax\Model\TaxClass\Source\Customer'],
 );
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 b4118569446c52a5c9b8a711f47e0aa1f12b53a1..dc21a5b7b0b5f209cf15b32521e312d2168e988a 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
@@ -318,7 +318,7 @@ return array(
         '\Magento\Framework\App\Filesystem::getDirectoryRead(\Magento\Framework\App\Filesystem::VAR_DIR)::search())'
     ),
     array('cloneIndexTable', 'Magento\Index\Model\Resource\AbstractResource'),
-    array('collectRoutes', 'Magento\Backend\App\Router\DefaultRouter'),
+    array('collectRoutes', 'Magento\Backend\App\Router'),
     array('collectRoutes', 'Magento\Core\App\Router\Base'),
     array('composeLocaleHierarchy', 'Magento\Translation\Helper\Data'),
     array('convertOldTaxData', 'Magento\Tax\Model\Resource\Setup'),
@@ -533,6 +533,7 @@ return array(
     array('getPriceFormatted', 'Magento\Customer\Block\Adminhtml\Edit\Tab\View\Sales'),
     array('getPrices', 'Magento\Bundle\Model\Product\Price', 'getTotalPrices()'),
     array('getPricesDependingOnTax', 'Magento\Bundle\Model\Product\Price', 'getTotalPrices()'),
+    array('getPriceTaxSql', 'Magento\Tax\Helper\Data'),
     array('getPrintUrl', 'Magento\Checkout\Block\Onepage\Success'),
     array('getPrintUrl', 'Magento\Sales\Block\Order\Info'),
     array('getProduct', 'Magento\Catalog\Model\Product\Type\AbstractType'),
@@ -628,6 +629,7 @@ return array(
     array('getTagsByType', 'Magento\Framework\App\CacheInterface', 'Magento_Cache_Frontend_Decorator_TagScope::getTag()'),
     array('getTaxAmount', 'Magento\Sales\Model\Quote\Item\AbstractItem'),
     array('getTaxRatesByProductClass', '', '_getAllRatesByProductClass'),
+    array('getAllRatesByProductClass', 'Magento\Tax\Helper\Data'),
     array(
         'getTemplateProcessor',
         'Magento\Newsletter\Helper\Data',
@@ -723,6 +725,7 @@ return array(
     array('isUserSavingAllowed', 'Magento\User\Model\Resource\User'),
     array('isVerbose', 'Magento\Framework\Shell'),
     array('isWindowsOs', 'Magento\TestFramework\Helper\Memory'),
+    array('joinTaxClass', 'Magento\Tax\Helper\Data'),
     array('load', 'Magento\Core\Model\Layout\Update', 'Magento\Core\Model\Layout\Merge'),
     array('loadBaseContents', 'Magento\Email\Model\Template'),
     array('loadBase', 'Magento\Core\Model\Config'),
@@ -1319,6 +1322,8 @@ return array(
     array('shouldEscapeMessage', 'Magento\Framework\View\Block\Messages'),
     array('isPathInDirectory', 'Magento\Framework\Filesystem\Directory\ReadInterface'),
     array('isSuper', '\Magento\Catalog\Model\Product'),
+    array('getCustomerTaxClassWithDefault', '\Magento\Tax\Model\Calculation\Rule'),
+    array('getProductTaxClassWithDefault', '\Magento\Tax\Model\Calculation\Rule'),
     array('isSuperGroup', '\Magento\Catalog\Model\Product'),
     array('isGrouped', '\Magento\Catalog\Model\Product'),
     array('isSuperConfig', '\Magento\Catalog\Model\Product'),
@@ -1636,6 +1641,7 @@ return array(
     array('getLimitVarName', 'Magento\Catalog\Block\Product\ProductList\Toolbar'),
     array('validatePHPVersion', 'Magento\Framework\Connect\Validator'),
     array('getOrderUrl', 'Magento\Catalog\Block\Product\ProductList\Toolbar'),
+    array('getAllOptionsForClass', 'Magento\Tax\Model\Calculation\Rule'),
     array('getModeUrl', 'Magento\Catalog\Block\Product\ProductList\Toolbar'),
     array('getLimitUrl', 'Magento\Catalog\Block\Product\ProductList\Toolbar'),
     array('_getAvailableLimit', 'Magento\Catalog\Block\Product\ProductList\Toolbar'),
@@ -1786,5 +1792,6 @@ return array(
     ['reset', 'Magento\CatalogInventory\Model\Stock\Item'],
     ['prepareValueForDuplicate', 'Magento\Catalog\Model\Product\Option\Value'],
     ['prepareOptionForDuplicate', '\Magento\Catalog\Model\Product\Option'],
+    ['addProductAdvanced', '\Magento\Sales\Model\Quote'],
     ['translateArray', 'Magento\Framework\App\Helper\AbstractHelper'],
 );
diff --git a/dev/tests/unit/filename b/dev/tests/unit/filename
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/dev/tests/unit/filename.csv b/dev/tests/unit/filename.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/dev/tests/unit/filename.invalid_type b/dev/tests/unit/filename.invalid_type
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/EditTest.php b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/EditTest.php
index 29a77fde9aba23064d6a4b9d5ae9267283317f30..906acb4478fd3c2a771164e8e1cd30d57f9c00cc 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/EditTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Block/System/Config/EditTest.php
@@ -147,7 +147,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
 
     public function testGetSaveUrl()
     {
-        $expectedUrl = '*/system_config_save/index';
+        $expectedUrl = '*/system_config/save';
         $expectedParams = array('_current' => true);
 
         $this->_urlModelMock->expects(
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/CacheTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanMediaTest.php
similarity index 92%
rename from dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/CacheTest.php
rename to dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanMediaTest.php
index bfd8d23014b5dc038fbbd538977fc05b332865a5..e0f61e5e7bc86b1bee96d1f410ffb1854900c5bb 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/CacheTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Cache/CleanMediaTest.php
@@ -21,11 +21,11 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml;
+namespace Magento\Backend\Controller\Adminhtml\Cache;
 
-class CacheTest extends \PHPUnit_Framework_TestCase
+class CleanMediaTest extends \PHPUnit_Framework_TestCase
 {
-    public function testCleanMediaAction()
+    public function testExecute()
     {
         // Wire object with mocks
         $response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
@@ -64,7 +64,9 @@ class CacheTest extends \PHPUnit_Framework_TestCase
         $context->expects($this->once())->method('getResponse')->will($this->returnValue($response));
         $context->expects($this->once())->method('getSession')->will($this->returnValue($session));
         $context->expects($this->once())->method('getMessageManager')->will($this->returnValue($messageManager));
-        $controller = $helper->getObject('Magento\Backend\Controller\Adminhtml\Cache', array('context' => $context));
+        $controller = $helper->getObject(
+            'Magento\Backend\Controller\Adminhtml\Cache\CleanMedia', array('context' => $context)
+        );
 
         // Setup expectations
         $mergeService = $this->getMock('Magento\Framework\View\Asset\MergeService', array(), array(), '', false);
@@ -98,6 +100,6 @@ class CacheTest extends \PHPUnit_Framework_TestCase
 
         $response->expects($this->once())->method('setRedirect')->with('redirect_url');
         // Run
-        $controller->cleanMediaAction();
+        $controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
similarity index 94%
rename from dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php
rename to dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
index 8ffa9107515d7537ace219fc5a04aface00d73e2..d1d8ca922229dad2ae015f2393fe242288459202 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/DashboardTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/Dashboard/TunnelTest.php
@@ -21,22 +21,22 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml;
+namespace Magento\Backend\Controller\Adminhtml\Dashboard;
 
-class DashboardTest extends \PHPUnit_Framework_TestCase
+class TunnelTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $_request;
 
     /**
-     * @var PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $_response;
 
     /**
-     * @var PHPUnit_Framework_MockObject_MockObject
+     * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $_objectManager;
 
@@ -72,7 +72,7 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
             'Magento\Framework\HTTP\ZendClient',
             array('setUri', 'setParameterGet', 'setConfig', 'request', 'getHeaders')
         );
-        /** @var $helper \Magento\Backend\Helper\Dashboard\Data|PHPUnit_Framework_MockObject_MockObject */
+        /** @var $helper \Magento\Backend\Helper\Dashboard\Data|\PHPUnit_Framework_MockObject_MockObject */
         $helper = $this->getMock(
             'Magento\Backend\Helper\Dashboard\Data',
             array('getChartDataHash'),
@@ -125,7 +125,7 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
         );
         $this->_response->expects($this->any())->method('getBody')->will($this->returnValue('success_msg'));
         $controller = $this->_factory($this->_request, $this->_response);
-        $controller->tunnelAction();
+        $controller->execute();
         $this->assertEquals('success_msg', $controller->getResponse()->getBody());
     }
 
@@ -152,7 +152,7 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
         );
         $this->_response->expects($this->once())->method('getHttpResponseCode')->will($this->returnValue(400));
         $controller = $this->_factory($this->_request, $this->_response);
-        $controller->tunnelAction();
+        $controller->execute();
         $this->assertEquals(400, $controller->getResponse()->getHttpResponseCode());
     }
 
@@ -232,7 +232,7 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
         );
         $this->_response->expects($this->once())->method('getHttpResponseCode')->will($this->returnValue(503));
         $controller = $this->_factory($this->_request, $this->_response);
-        $controller->tunnelAction();
+        $controller->execute();
         $this->assertEquals(503, $controller->getResponse()->getHttpResponseCode());
     }
 
@@ -241,12 +241,12 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
      *
      * @param \Magento\Framework\App\Request\Http $request
      * @param \Magento\Framework\App\Response\Http|null $response
-     * @return \Magento\Backend\Controller\Adminhtml\Dashboard|PHPUnit_Framework_MockObject_MockObject
+     * @return \Magento\Backend\Controller\Adminhtml\Dashboard|\PHPUnit_Framework_MockObject_MockObject
      */
     protected function _factory($request, $response = null)
     {
         if (!$response) {
-            /** @var $response \Magento\Framework\App\ResponseInterface|PHPUnit_Framework_MockObject_MockObject */
+            /** @var $response \Magento\Framework\App\ResponseInterface|\PHPUnit_Framework_MockObject_MockObject */
             $response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
             $response->headersSentThrowsException = false;
         }
@@ -270,6 +270,6 @@ class DashboardTest extends \PHPUnit_Framework_TestCase
             'frontController' => $varienFront
         );
         $context = $helper->getObject('Magento\Backend\App\Action\Context', $arguments);
-        return new \Magento\Backend\Controller\Adminhtml\Dashboard($context);
+        return new \Magento\Backend\Controller\Adminhtml\Dashboard\Tunnel($context);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
similarity index 97%
rename from dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php
rename to dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
index b002e37a29b3e962f6ceec86381cf7ecdc839b0a..fc8a971c2e59f57470278ab92ac6fabc4f262097 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/AccountTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Account/SaveTest.php
@@ -23,9 +23,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Backend\Controller\Adminhtml\System;
+namespace Magento\Backend\Controller\Adminhtml\System\Account;
 
-class AccountTest extends \PHPUnit_Framework_TestCase
+class SaveTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\Backend\Controller\Adminhtml\System\Account */
     protected $_controller;
@@ -151,7 +151,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase
         $args = array('context' => $contextMock);
 
         $testHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_controller = $testHelper->getObject('Magento\Backend\Controller\Adminhtml\System\Account', $args);
+        $this->_controller = $testHelper->getObject('Magento\Backend\Controller\Adminhtml\System\Account\Save', $args);
     }
 
     public function testSaveAction()
@@ -229,6 +229,6 @@ class AccountTest extends \PHPUnit_Framework_TestCase
 
         $this->_messagesMock->expects($this->once())->method('addSuccess')->with($this->equalTo($testedMessage));
 
-        $this->_controller->saveAction();
+        $this->_controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php
index cd64049b44185cedc05ca137c77acc75930aae6a..fd073c45107cd59530c9c4caa473fbf17585fdfd 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Controller/Adminhtml/System/Config/SaveTest.php
@@ -201,7 +201,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($backendConfigMock)
         );
 
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionWithNotAllowedSection()
@@ -222,7 +222,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($backendConfigMock)
         );
 
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionSaveState()
@@ -243,7 +243,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue($data)
         );
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionGetGroupForSave()
@@ -294,7 +294,7 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         );
         $backendConfigMock->expects($this->once())->method('save');
 
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionSaveAdvanced()
@@ -320,6 +320,6 @@ class SaveTest extends \PHPUnit_Framework_TestCase
         $backendConfigMock->expects($this->once())->method('save');
 
         $this->_cacheMock->expects($this->once())->method('clean')->with(\Zend_Cache::CLEANING_MODE_ALL);
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
index 915bb123be5836a1e8f11d033318b13e3f629f8a..a843f53ee202c0c1ae9d350beb1c9f6b21fce1aa 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ConfigTest.php
@@ -121,7 +121,11 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $this->_menuMock = $this->getMock('Magento\Backend\Model\Menu', array(), array(), '', false);
+        $this->_menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
 
         $this->_menuBuilderMock = $this->getMock('Magento\Backend\Model\Menu\Builder', array(), array(), '', false);
 
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
index bdae94029bd78734b3358970cdaa591624c79e58..719d2f46ad028564a7d2689d7566edb5e94043f6 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/Menu/ItemTest.php
@@ -251,7 +251,11 @@ class ItemTest extends \PHPUnit_Framework_TestCase
 
     public function testGetChildrenCreatesSubmenuOnFirstCall()
     {
-        $menuMock = $this->getMock('Magento\Backend\Model\Menu', array(), array(), '', false);
+        $menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
 
         $this->_menuFactoryMock->expects($this->once())->method('create')->will($this->returnValue($menuMock));
 
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
index dcad003b470884e0f9ee69d0c60a86c59338eb4f..084410f0785de25a8fe32f05abaa578a14c87606 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/MenuTest.php
@@ -79,7 +79,7 @@ class MenuTest extends \PHPUnit_Framework_TestCase
 
     public function testAddToItem()
     {
-        $subMenu = $this->getMock("Magento\Backend\Model\Menu", array(), array($this->_logger));
+        $subMenu = $this->getMock('Magento\Backend\Model\Menu', array(), array($this->_logger));
         $subMenu->expects($this->once())->method("add")->with($this->_items['item2']);
 
         $this->_items['item1']->expects($this->once())->method("getChildren")->will($this->returnValue($subMenu));
@@ -152,7 +152,11 @@ class MenuTest extends \PHPUnit_Framework_TestCase
         $this->_model->add($this->_items['item2']);
         $this->_model->add($this->_items['item3']);
 
-        $subMenu = $this->getMock("Magento\Backend\Model\Menu", array(), array(), '', false);
+        $subMenu = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
         $subMenu->expects($this->once())->method("add")->with($this->_items['item3']);
 
         $this->_items['item1']->expects($this->once())->method("getChildren")->will($this->returnValue($subMenu));
@@ -201,7 +205,11 @@ class MenuTest extends \PHPUnit_Framework_TestCase
 
     public function testRemoveRemovesMenuItemRecursively()
     {
-        $menuMock = $this->getMock('Magento\Backend\Model\Menu', array(), array(), '', false);
+        $menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
         $menuMock->expects($this->once())->method('remove')->with($this->equalTo('item2'));
 
         $this->_items['item1']->expects($this->any())->method('hasChildren')->will($this->returnValue(true));
diff --git a/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php b/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
index cd372b32e233a6d1838f371d87fdfbc09bcf5f20..059d70552d63039e9a17ca0198920a91a3133787 100644
--- a/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
+++ b/dev/tests/unit/testsuite/Magento/Backend/Model/UrlTest.php
@@ -93,7 +93,11 @@ class UrlTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->_menuMock = $this->getMock('Magento\Backend\Model\Menu', array(), array(), '', false);
+        $this->_menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
 
         $this->_menuConfigMock = $this->getMock('Magento\Backend\Model\Menu\Config', array(), array(), '', false);
         $this->_menuConfigMock->expects($this->any())->method('getMenu')->will($this->returnValue($this->_menuMock));
diff --git a/dev/tests/unit/testsuite/Magento/Captcha/Model/CaptchaFactoryTest.php b/dev/tests/unit/testsuite/Magento/Captcha/Model/CaptchaFactoryTest.php
index db185840e7ca4364600cd39c322eb19cb5bd7137..5a45c63b5b6a8376a653afd0340e4b5f84f512f2 100644
--- a/dev/tests/unit/testsuite/Magento/Captcha/Model/CaptchaFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Captcha/Model/CaptchaFactoryTest.php
@@ -60,7 +60,7 @@ class CaptchaFactoryTest extends \PHPUnit_Framework_TestCase
     {
         $captchaType = 'wrong_instance';
 
-        $defaultCaptchaMock = $this->getMock('stdClass', array(), array(), '', false);
+        $defaultCaptchaMock = $this->getMock('stdClass');
 
         $this->_objectManagerMock->expects(
             $this->once()
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJsonTest.php
similarity index 88%
rename from dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php
rename to dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJsonTest.php
index 975711fdd96aa7ddda0e7d76e0354d12b5097bdb..3e713801168f3a6a074a78a415b20e894b65fdae 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/WidgetTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/CategoriesJsonTest.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,9 +22,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller\Adminhtml\Category;
+namespace Magento\Catalog\Controller\Adminhtml\Category\Widget;
 
-class WidgetTest extends \PHPUnit_Framework_TestCase
+class CategoriesJsonTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Catalog\Controller\Adminhtml\Category\Widget
@@ -95,7 +96,9 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
         $context->expects($this->once())->method('getRequest')->will($this->returnValue($this->requestMock));
         $context->expects($this->once())->method('getResponse')->will($this->returnValue($this->responseMock));
         $this->registryMock = $this->getMock('Magento\Framework\Registry', array(), array(), '', false);
-        $this->controller = new \Magento\Catalog\Controller\Adminhtml\Category\Widget($context, $this->registryMock);
+        $this->controller = new \Magento\Catalog\Controller\Adminhtml\Category\Widget\CategoriesJson(
+            $context, $this->registryMock
+        );
     }
 
     protected function _getTreeBlock()
@@ -110,16 +113,7 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
         $this->viewMock->expects($this->once())->method('getLayout')->will($this->returnValue($this->layoutMock));
     }
 
-    public function testChooserAction()
-    {
-        $this->_getTreeBlock();
-        $testHtml = '<div>Some test html</div>';
-        $this->chooserBlockMock->expects($this->once())->method('toHtml')->will($this->returnValue($testHtml));
-        $this->responseMock->expects($this->once())->method('setBody')->with($this->equalTo($testHtml));
-        $this->controller->chooserAction();
-    }
-
-    public function testCategoriesJsonAction()
+    public function testExecute()
     {
         $this->_getTreeBlock();
         $testCategoryId = 1;
@@ -137,6 +131,6 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
         $testHtml = '<div>Some test html</div>';
         $this->chooserBlockMock->expects($this->once())->method('getTreeJson')->will($this->returnValue($testHtml));
         $this->responseMock->expects($this->once())->method('representJson')->with($this->equalTo($testHtml));
-        $this->controller->categoriesJsonAction();
+        $this->controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/ChooserTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/ChooserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..179c0dd8026aed7dab16988cecf5da042967ff26
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Category/Widget/ChooserTest.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Category\Widget;
+
+class ChooserTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Controller\Adminhtml\Category\Widget
+     */
+    protected $controller;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    /**
+     * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Backend\Model\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $chooserBlockMock;
+
+    /**
+     * @var \Magento\Core\Model\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * @var \Magento\TestFramework\Helper\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    public function setUp()
+    {
+        $this->responseMock = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
+        $this->requestMock = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false);
+        $this->viewMock = $this->getMock('Magento\Backend\Model\View', array('getLayout'), array(), '', false);
+        $this->objectManagerMock = $this->getMock(
+            'Magento\Framework\ObjectManager\ObjectManager',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $context = $this->getMock(
+            'Magento\Backend\App\Action\Context',
+            array('getRequest', 'getResponse', 'getMessageManager', 'getSession'),
+            $helper->getConstructArguments(
+                'Magento\Backend\App\Action\Context',
+                array(
+                    'response' => $this->responseMock,
+                    'request' => $this->requestMock,
+                    'view' => $this->viewMock,
+                    'objectManager' => $this->objectManagerMock
+                )
+            )
+        );
+        $context->expects($this->once())->method('getRequest')->will($this->returnValue($this->requestMock));
+        $context->expects($this->once())->method('getResponse')->will($this->returnValue($this->responseMock));
+        $this->controller = new \Magento\Catalog\Controller\Adminhtml\Category\Widget\Chooser(
+            $context
+        );
+    }
+
+    protected function _getTreeBlock()
+    {
+        $this->chooserBlockMock = $this->getMock(
+            'Magento\Catalog\Block\Adminhtml\Category\Widget\Chooser', array(), array(), '', false
+        );
+        $this->layoutMock = $this->getMock('Magento\Core\Model\Layout', array('createBlock'), array(), '', false);
+        $this->layoutMock->expects($this->once())->method('createBlock')->will(
+            $this->returnValue($this->chooserBlockMock)
+        );
+        $this->viewMock->expects($this->once())->method('getLayout')->will($this->returnValue($this->layoutMock));
+    }
+
+    public function testExecute()
+    {
+        $this->_getTreeBlock();
+        $testHtml = '<div>Some test html</div>';
+        $this->chooserBlockMock->expects($this->once())->method('toHtml')->will($this->returnValue($testHtml));
+        $this->responseMock->expects($this->once())->method('setBody')->with($this->equalTo($testHtml));
+        $this->controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/MassStatusTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/MassStatusTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a317dbd420adfde847dbc29e07f1c73f6c158eff
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/MassStatusTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class MassStatusTest extends \Magento\Catalog\Controller\Adminhtml\ProductTest
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $priceProcessor;
+
+    protected function setUp()
+    {
+        $this->priceProcessor = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Price\Processor')
+            ->disableOriginalConstructor()->getMock();
+
+        $productBuilder = $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Builder')->setMethods([
+                'build'
+            ])->disableOriginalConstructor()->getMock();
+
+        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')->disableOriginalConstructor()
+            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])->getMock();
+        $product->expects($this->any())->method('getTypeId')->will($this->returnValue('simple'));
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue('1'));
+        $productBuilder->expects($this->any())->method('build')->will($this->returnValue($product));
+
+        $this->action = new \Magento\Catalog\Controller\Adminhtml\Product\MassStatus(
+            $this->initContext(),
+            $productBuilder,
+            $this->priceProcessor
+        );
+
+    }
+
+    public function testMassStatusAction()
+    {
+        $this->priceProcessor->expects($this->once())->method('reindexList');
+        $this->action->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/NewActionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/NewActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..21d5d89f6972524b6bee9f446eeebd7123b21b11
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/Product/NewActionTest.php
@@ -0,0 +1,65 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Controller\Adminhtml\Product;
+
+class NewActionTest extends \Magento\Catalog\Controller\Adminhtml\ProductTest
+{
+    protected $action;
+
+    protected function setUp()
+    {
+        $productBuilder = $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Builder')->setMethods([
+                'build'
+            ])->disableOriginalConstructor()->getMock();
+
+        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')->disableOriginalConstructor()
+            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])->getMock();
+        $product->expects($this->any())->method('getTypeId')->will($this->returnValue('simple'));
+        $product->expects($this->any())->method('getStoreId')->will($this->returnValue('1'));
+        $productBuilder->expects($this->any())->method('build')->will($this->returnValue($product));
+
+        $this->action = new \Magento\Catalog\Controller\Adminhtml\Product\NewAction(
+            $this->initContext(),
+            $productBuilder,
+            $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter')
+                ->disableOriginalConstructor()->getMock()
+        );
+
+    }
+
+    /**
+     * Testing `newAction` method
+     */
+    public function testExecute()
+    {
+        $this->action->getRequest()->expects($this->at(0))->method('getParam')
+            ->with('set')->will($this->returnValue(true));
+        $this->action->getRequest()->expects($this->at(1))->method('getParam')
+            ->with('popup')->will($this->returnValue(true));
+        $this->action->getRequest()->expects($this->any())->method('getFullActionName')
+            ->will($this->returnValue('catalog_product_new'));
+        $this->action->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
index 85d3f8bc32a72648e2d0d8feafee01539f485223..b9eef8dad50eb94e1bd9275d90b054832c19e402 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Adminhtml/ProductTest.php
@@ -23,54 +23,17 @@
  */
 namespace Magento\Catalog\Controller\Adminhtml;
 
-class ProductTest extends \PHPUnit_Framework_TestCase
+abstract class ProductTest extends \PHPUnit_Framework_TestCase
 {
-    /**
-     * @var \Magento\Catalog\Controller\Adminhtml\Product
-     */
-    protected $_controller;
-
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
     protected $context;
 
     /**
-     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor
+     * @var \Magento\Catalog\Controller\Product
      */
-    protected $_priceProcessor;
-
-    public function setUp()
-    {
-        $this->initContext();
-        $this->_priceProcessor = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Price\Processor')
-            ->disableOriginalConstructor()->getMock();
-
-        $productBuilder = $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Builder')->setMethods([
-            'build'
-        ])->disableOriginalConstructor()->getMock();
-
-        $product = $this->getMockBuilder('\Magento\Catalog\Model\Product')->disableOriginalConstructor()
-            ->setMethods(['getTypeId', 'getStoreId', '__sleep', '__wakeup'])->getMock();
-        $product->expects($this->any())->method('getTypeId')->will($this->returnValue('simple'));
-        $product->expects($this->any())->method('getStoreId')->will($this->returnValue('1'));
-        $productBuilder->expects($this->any())->method('build')->will($this->returnValue($product));
-
-        $this->_controller = new \Magento\Catalog\Controller\Adminhtml\Product(
-            $this->context,
-            $this->getMock('Magento\Framework\Registry', array(), array(), '', false),
-            $this->getMock('Magento\Framework\Stdlib\DateTime\Filter\Date', array(), array(), '', false),
-            $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Initialization\Helper')
-                ->disableOriginalConstructor()->getMock(),
-            $this->getMockBuilder('Magento\Catalog\Controller\Adminhtml\Product\Initialization\StockDataFilter')
-                ->disableOriginalConstructor()->getMock(),
-            $this->getMock('Magento\Catalog\Model\Product\Copier', array(), array(), '', false),
-            $productBuilder,
-            $this->getMock('Magento\Catalog\Model\Product\Validator', array(), array(), '', false),
-            $this->getMock('Magento\Catalog\Model\Product\TypeTransitionManager', array(), array(), '', false),
-            $this->_priceProcessor
-        );
-    }
+    protected $action;
 
     /**
      *  Init context object
@@ -156,26 +119,6 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->context->expects($this->any())->method('getSession')->will($this->returnValue($sessionMock));
         $this->context->expects($this->any())->method('getActionFlag')->will($this->returnValue($actionFlagMock));
         $this->context->expects($this->any())->method('getHelper')->will($this->returnValue($helperDataMock));
-    }
-
-    public function testMassStatusAction()
-    {
-        $this->_priceProcessor->expects($this->once())->method('reindexList');
-
-        $this->_controller->massStatusAction();
-    }
-
-    /**
-     * Testing `newAction` method
-     */
-    public function testNewAction()
-    {
-        $this->_controller->getRequest()->expects($this->at(0))->method('getParam')
-            ->with('set')->will($this->returnValue(true));
-        $this->_controller->getRequest()->expects($this->at(1))->method('getParam')
-            ->with('popup')->will($this->returnValue(true));
-        $this->_controller->getRequest()->expects($this->any())->method('getFullActionName')
-            ->will($this->returnValue('catalog_product_new'));
-        $this->_controller->newAction();
+        return $this->context;
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/CategoryTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Category/ViewTest.php
similarity index 96%
rename from dev/tests/unit/testsuite/Magento/Catalog/Controller/CategoryTest.php
rename to dev/tests/unit/testsuite/Magento/Catalog/Controller/Category/ViewTest.php
index 7a4c1a4768bf13b5c1c98b6868226baeca7bfdf7..7452d0e3d2e5eeb6798163cc5dc8c5e285317a8f 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/CategoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Controller/Category/ViewTest.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Catalog\Controller;
+namespace Magento\Catalog\Controller\Category;
 
 use Magento\Framework\App\Action\Action;
 use Magento\TestFramework\Helper\ObjectManager;
@@ -30,7 +30,7 @@ use Magento\TestFramework\Helper\ObjectManager;
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  * @SuppressWarnings(PHPMD.TooManyFields)
  */
-class CategoryTest extends \PHPUnit_Framework_TestCase
+class ViewTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -110,7 +110,7 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Catalog\Controller\Category
      */
-    protected $controller;
+    protected $action;
 
     public function setUp()
     {
@@ -145,11 +145,11 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
         $this->catalogDesign = $this->getMock('Magento\Catalog\Model\Design', [], [], '', false);
         $this->layoutHelper = $this->getMock('Magento\Theme\Helper\Layout', [], [], '', false);
 
-        $this->controller = (new ObjectManager($this))->getObject('Magento\Catalog\Controller\Category', [
+        $this->action = (new ObjectManager($this))->getObject('Magento\Catalog\Controller\Category\View', [
             'context' => $this->context,
+            'catalogDesign' => $this->catalogDesign,
             'categoryFactory' => $this->categoryFactory,
             'storeManager' => $this->storeManager,
-            'catalogDesign' => $this->catalogDesign,
         ]);
     }
 
@@ -181,6 +181,6 @@ class CategoryTest extends \PHPUnit_Framework_TestCase
 
         $this->layoutHelper->expects($this->once())->method('applyHandle')->with($pageLayout);
 
-        $this->controller->viewAction();
+        $this->action->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Controller/ProductTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Controller/ProductTest.php
deleted file mode 100644
index 55405a78ecc2867c99b72ec0c44c5126da56077c..0000000000000000000000000000000000000000
--- a/dev/tests/unit/testsuite/Magento/Catalog/Controller/ProductTest.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Catalog\Controller;
-
-class ProductTest extends \PHPUnit_Framework_TestCase
-{
-    public function testControllerImplementsProductViewInterface()
-    {
-        $this->assertInstanceOf(
-            'Magento\Catalog\Controller\Product\View\ViewInterface',
-            $this->getMock('Magento\Catalog\Controller\Product', array(), array(), '', false)
-        );
-    }
-}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/AbstractActionTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/AbstractActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..69635ed70d33988f028e6c82119c73e808b4625c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/AbstractActionTest.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav;
+
+class AbstractActionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_eavDecimalFactoryMock;
+
+    /**
+     * @var \Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_eavSourceFactoryMock;
+
+    protected function setUp()
+    {
+        $this->_eavDecimalFactoryMock = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $this->_eavSourceFactoryMock = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+
+        $this->_model = $this->getMockForAbstractClass(
+            'Magento\Catalog\Model\Indexer\Product\Eav\AbstractAction',
+            array($this->_eavDecimalFactoryMock, $this->_eavSourceFactoryMock)
+        );
+    }
+
+    public function testGetIndexers()
+    {
+        $expectedIndexers = array(
+            'source' => 'source_instance',
+            'decimal' => 'decimal_instance'
+        );
+
+        $this->_eavSourceFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($expectedIndexers['source']));
+
+        $this->_eavDecimalFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($expectedIndexers['decimal']));
+
+        $this->assertEquals($expectedIndexers, $this->_model->getIndexers());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Unknown EAV indexer type "unknown_type".
+     */
+    public function testGetIndexerWithUnknownTypeThrowsException()
+    {
+        $this->_eavSourceFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue('return_value'));
+
+        $this->_eavDecimalFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue('return_value'));
+
+        $this->_model->getIndexer('unknown_type');
+    }
+
+    public function testGetIndexer()
+    {
+        $this->_eavSourceFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue('source_return_value'));
+
+        $this->_eavDecimalFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue('decimal_return_value'));
+
+        $this->assertEquals('source_return_value', $this->_model->getIndexer('source'));
+    }
+
+    public function testReindexWithoutArgumentsExecutesReindexAll()
+    {
+        $eavSource = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $eavDecimal = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Indexer\Eav\Decimal')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $eavDecimal->expects($this->once())
+            ->method('reindexAll');
+
+        $eavSource->expects($this->once())
+            ->method('reindexAll');
+
+        $this->_eavSourceFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($eavSource));
+
+        $this->_eavDecimalFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($eavDecimal));
+
+        $this->_model->reindex();
+    }
+
+    public function testReindexWithNotNullArgumentExecutesReindexEntities()
+    {
+        $ids = array(1, 2, 3);
+
+        $eavSource = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Indexer\Eav\Source')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $eavDecimal = $this->getMockBuilder('Magento\Catalog\Model\Resource\Product\Indexer\Eav\Decimal')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $eavDecimal->expects($this->once())
+            ->method('reindexEntities')
+            ->with($ids);
+
+        $eavSource->expects($this->once())
+            ->method('reindexEntities')
+            ->with($ids);
+
+        $this->_eavSourceFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($eavSource));
+
+        $this->_eavDecimalFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($eavDecimal));
+
+        $this->_model->reindex($ids);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fd98f4132bb2be6880bda0ff1fc5e23fceb2552
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/FullTest.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+class FullTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecuteWithAdapterErrorThrowsException()
+    {
+        $eavDecimalFactory = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\DecimalFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $eavSourceFactory = $this->getMock(
+            'Magento\Catalog\Model\Resource\Product\Indexer\Eav\SourceFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+
+        $exceptionMessage = 'exception message';
+        $exception = new \Exception($exceptionMessage);
+
+        $eavDecimalFactory->expects($this->once())
+            ->method('create')
+            ->will($this->throwException($exception));
+
+        $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full(
+            $eavDecimalFactory,
+            $eavSourceFactory
+        );
+
+        $this->setExpectedException('\Magento\Catalog\Exception', $exceptionMessage);
+
+        $model->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..9400902c5bfc5e2c7ec7472a67a03888de8bef75
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class RowTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Row
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->_model = $objectManager->getObject('Magento\Catalog\Model\Indexer\Product\Eav\Action\Row');
+    }
+
+    /**
+     * @expectedException \Magento\Catalog\Exception
+     * @expectedExceptionMessage Could not rebuild index for undefined product
+     */
+    public function testEmptyId()
+    {
+        $this->_model->execute(null);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..721d3da9f5bf7669b6488605f29fe1f19eae93bf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Action/RowsTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Action;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class RowsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->_model = $objectManager->getObject('Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows');
+    }
+
+    /**
+     * @expectedException \Magento\Catalog\Exception
+     * @expectedExceptionMessage Bad value was supplied.
+     */
+    public function testEmptyIds()
+    {
+        $this->_model->execute(null);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilterTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4700d290c2dfda009d5afdeab3ea2bc52f5cd9d5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSet/IndexableAttributeFilterTest.php
@@ -0,0 +1,98 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet;
+
+class IndexableAttributeFilterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testFilter()
+    {
+        $catalogResourceMock = $this->getMockBuilder('Magento\Catalog\Model\Resource\Eav\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(array('load', 'isIndexable', '__wakeup'))
+            ->getMock();
+        $catalogResourceMock->expects($this->any())
+            ->method('load')
+            ->will($this->returnSelf());
+        $catalogResourceMock->expects($this->at(1))
+            ->method('isIndexable')
+            ->will($this->returnValue(true));
+        $catalogResourceMock->expects($this->at(2))
+            ->method('isIndexable')
+            ->will($this->returnValue(false));
+
+        $eavAttributeFactoryMock = $this->getMockBuilder('Magento\Catalog\Model\Resource\Eav\AttributeFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(array('create'))
+            ->getMock();
+        $eavAttributeFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($catalogResourceMock));
+
+        $attributeMock1 = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getId', 'getAttributeId', 'getAttributeCode', 'load', '__wakeup'))
+            ->getMock();
+        $attributeMock1->expects($this->any())
+            ->method('getAttributeCode')
+            ->will($this->returnValue('indexable_attribute'));
+        $attributeMock1->expects($this->any())
+            ->method('load')
+            ->will($this->returnSelf());
+
+        $attributeMock2 = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getId', 'getAttributeId', 'getAttributeCode', 'load', '__wakeup'))
+            ->getMock();
+        $attributeMock2->expects($this->any())
+            ->method('getAttributeCode')
+            ->will($this->returnValue('non_indexable_attribute'));
+        $attributeMock2->expects($this->any())
+            ->method('load')
+            ->will($this->returnSelf());
+
+        $attributes = array($attributeMock1, $attributeMock2);
+
+        $groupMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Group')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getAttributes', '__wakeup'))
+            ->getMock();
+        $groupMock->expects($this->once())
+            ->method('getAttributes')
+            ->will($this->returnValue($attributes));
+
+        $attributeSetMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Set')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getGroups', '__wakeup'))
+            ->getMock();
+        $attributeSetMock->expects($this->once())
+            ->method('getGroups')
+            ->will($this->returnValue(array($groupMock)));
+
+        $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet\IndexableAttributeFilter(
+            $eavAttributeFactoryMock
+        );
+
+        $this->assertEquals(array('indexable_attribute'), $model->filter($attributeSetMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSetTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSetTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..d7fd416375e9b1896509b1090329dd60680322b5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/AttributeSetTest.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin;
+
+class AttributeSetTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAroundSave()
+    {
+        $eavProcessorMock = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Processor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $eavProcessorMock->expects($this->once())
+            ->method('markIndexerAsInvalid');
+
+        $filter = $this->getMockBuilder(
+            'Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet\IndexableAttributeFilter'
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $filter->expects($this->at(0))
+            ->method('filter')
+            ->will($this->returnValue(array(1, 2, 3)));
+        $filter->expects($this->at(1))
+            ->method('filter')
+            ->will($this->returnValue(array(1, 2)));
+
+        $subjectMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Set')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $subjectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(11));
+
+        $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Plugin\AttributeSet(
+            $eavProcessorMock,
+            $filter
+        );
+
+        $closure  = function () use ($subjectMock) {
+            return $subjectMock;
+        };
+
+        $this->assertEquals(
+            $subjectMock,
+            $model->aroundSave($subjectMock, $closure)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/ImportTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/ImportTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..950f08716d135937e1d8765427ccc6902161faf8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/ImportTest.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin;
+
+class ImportTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAfterImportSource()
+    {
+        $eavProcessorMock = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Processor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $eavProcessorMock->expects($this->once())
+            ->method('markIndexerAsInvalid');
+
+        $subjectMock = $this->getMockBuilder('Magento\ImportExport\Model\Import')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $import = new \stdClass();
+
+        $model = new \Magento\CatalogImportExport\Model\Indexer\Product\Eav\Plugin\Import($eavProcessorMock);
+
+        $this->assertEquals(
+            $import,
+            $model->afterImportSource($subjectMock, $import)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreViewTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreViewTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f81984607f38a21174e936e592693b75c902a40d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/Eav/Plugin/StoreViewTest.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product\Eav\Plugin;
+
+class StoreViewTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @param array $data
+     * @dataProvider beforeSaveDataProvider
+     */
+    public function testBeforeSave(array $data)
+    {
+        $eavProcessorMock = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Processor')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $matcher = $data['matcher'];
+        $eavProcessorMock->expects($this->$matcher())
+            ->method('markIndexerAsInvalid');
+
+        $subjectMock = $this->getMockBuilder('Magento\Store\Model\Resource\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $objectMock = $this->getMockBuilder('Magento\Framework\Model\AbstractModel')
+            ->disableOriginalConstructor()
+            ->setMethods(array('getId', 'dataHasChangedFor', 'getIsActive', '__wakeup'))
+            ->getMock();
+        $objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($data['object_id']));
+        $objectMock->expects($this->any())
+            ->method('dataHasChangedFor')
+            ->with('group_id')
+            ->will($this->returnValue($data['has_group_id_changed']));
+        $objectMock->expects($this->any())
+            ->method('getIsActive')
+            ->will($this->returnValue($data['is_active']));
+
+        $model = new \Magento\Catalog\Model\Indexer\Product\Eav\Plugin\StoreView($eavProcessorMock);
+        $model->beforeSave($subjectMock, $objectMock);
+    }
+
+    /**
+     * @return array
+     */
+    public function beforeSaveDataProvider()
+    {
+        return array(
+            array(
+                array(
+                    'matcher' => 'once',
+                    'object_id' => 1,
+                    'has_group_id_changed' => true,
+                    'is_active' => true
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'never',
+                    'object_id' => 1,
+                    'has_group_id_changed' => false,
+                    'is_active' => true
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'never',
+                    'object_id' => 1,
+                    'has_group_id_changed' => true,
+                    'is_active' => false
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'never',
+                    'object_id' => 1,
+                    'has_group_id_changed' => false,
+                    'is_active' => false
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'once',
+                    'object_id' => 0,
+                    'has_group_id_changed' => true,
+                    'is_active' => true
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'once',
+                    'object_id' => 0,
+                    'has_group_id_changed' => false,
+                    'is_active' => true
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'never',
+                    'object_id' => 0,
+                    'has_group_id_changed' => true,
+                    'is_active' => false
+                )
+            ),
+            array(
+                array(
+                    'matcher' => 'never',
+                    'object_id' => 0,
+                    'has_group_id_changed' => false,
+                    'is_active' => false
+                )
+            ),
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/EavTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/EavTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5d911679e96a14fd4c3cbc57d6a7e6d9095b020f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Indexer/Product/EavTest.php
@@ -0,0 +1,97 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Catalog\Model\Indexer\Product;
+
+class EavTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Row|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_productEavIndexerRow;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_productEavIndexerRows;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Action\Full|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_productEavIndexerFull;
+
+    protected function setUp()
+    {
+        $this->_productEavIndexerRow = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Action\Row')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_productEavIndexerRows = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Action\Rows')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_productEavIndexerFull = $this->getMockBuilder('Magento\Catalog\Model\Indexer\Product\Eav\Action\Full')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_model = new \Magento\Catalog\Model\Indexer\Product\Eav(
+            $this->_productEavIndexerRow,
+            $this->_productEavIndexerRows,
+            $this->_productEavIndexerFull
+        );
+    }
+
+    public function testExecuteAndExecuteList()
+    {
+        $ids = [1, 2, 3];
+        $this->_productEavIndexerRow->expects($this->any())
+            ->method('execute')
+            ->with($ids);
+
+        $this->_model->execute($ids);
+        $this->_model->executeList($ids);
+    }
+
+    public function testExecuteFull()
+    {
+        $this->_productEavIndexerFull->expects($this->once())
+            ->method('execute');
+
+        $this->_model->executeFull();
+    }
+
+    public function testExecuteRow()
+    {
+        $id = 11;
+        $this->_productEavIndexerRow->expects($this->once())
+            ->method('execute')
+            ->with($id);
+
+        $this->_model->executeRow($id);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
index dc1f99f0916893cd3a1ce552e2f6a72a79f831f1..9be7df61744a839582fb3bd3f9a75aa43a9d3874 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Model/Resource/Eav/AttributeTest.php
@@ -35,6 +35,11 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
      */
     protected $_processor;
 
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Eav\Processor
+     */
+    protected $_eavProcessor;
+
     public function setUp()
     {
         $this->_processor = $this->getMock(
@@ -45,6 +50,14 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
             false
         );
 
+        $this->_eavProcessor = $this->getMock(
+            '\Magento\Catalog\Model\Indexer\Product\Eav\Processor',
+            array(),
+            array(),
+            '',
+            false
+        );
+
         $eventManagerMock = $this->getMock('Magento\Framework\Event\ManagerInterface', array(), array(), '', false);
 
         $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface', array(), array(), '', false);
@@ -89,8 +102,8 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
             $this->getMock('Magento\Framework\Stdlib\DateTime\TimezoneInterface', array(), array(), '', false),
             $this->getMock('Magento\Catalog\Model\Product\ReservedAttributeList', array(), array(), '', false),
             $this->getMock('Magento\Framework\Locale\ResolverInterface', array(), array(), '', false),
-            $this->getMock('Magento\Index\Model\Indexer', array(), array(), '', false),
             $this->_processor,
+            $this->_eavProcessor,
             $this->getMock('\Magento\Catalog\Helper\Product\Flat\Indexer', array(), array(), '', false),
             $this->getMock('\Magento\Catalog\Model\Attribute\LockValidatorInterface'),
             $resourceMock,
@@ -108,10 +121,22 @@ class AttributeTest extends \PHPUnit_Framework_TestCase
         $this->_model->save();
     }
 
-    public function testIndexerAfterDeleteAttribute()
+    public function testIndexerAfterSaveScopeChangeAttribute()
     {
         $this->_processor->expects($this->once())->method('markIndexerAsInvalid');
 
+        $this->_model->setOrigData('is_global', \Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_STORE);
+        $this->_model->setOrigData('used_in_product_listing', 1);
+        $this->_model->setIsGlobal(\Magento\Catalog\Model\Resource\Eav\Attribute::SCOPE_GLOBAL);
+        $this->_model->save();
+
+    }
+
+    public function testIndexerAfterDeleteAttribute()
+    {
+        $this->_processor->expects($this->once())->method('markIndexerAsInvalid');
+        $this->_model->setOrigData('id', 2);
+        $this->_model->setOrigData('used_in_product_listing', 1);
         $this->_model->delete();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
index 8ea497367bef5efc74297dd9148374df32df5ef0..f8eac777ce6f13e146c1fe6f187e0c5d36dfd0f8 100644
--- a/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Catalog/Pricing/Price/BasePriceTest.php
@@ -89,15 +89,24 @@ class BasePriceTest extends \PHPUnit_Framework_TestCase
             'group_price' => $this->groupPriceMock,
             'special_price' => $this->specialPriceMock
         ];
-        $this->basePrice = new BasePrice($this->saleableItemMock, $qty, $this->calculatorMock);
+
+        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->basePrice = $helper->getObject('\Magento\Catalog\Pricing\Price\BasePrice',
+            array(
+                'saleableItem' => $this->saleableItemMock,
+                'quantity' => $qty,
+                'calculator' => $this->calculatorMock
+            )
+        );
     }
 
     /**
      * test method getValue
+     *
+     * @dataProvider getValueDataProvider
      */
-    public function testGetValue()
+    public function testGetValue($specialPriceValue, $expectedResult)
     {
-        $specialPriceValue = 77;
         $this->priceInfoMock->expects($this->once())
             ->method('getPrices')
             ->will($this->returnValue($this->prices));
@@ -107,9 +116,14 @@ class BasePriceTest extends \PHPUnit_Framework_TestCase
         $this->groupPriceMock->expects($this->exactly(2))
             ->method('getValue')
             ->will($this->returnValue(99));
-        $this->specialPriceMock->expects($this->exactly(2))
+        $this->specialPriceMock->expects($this->any())
             ->method('getValue')
             ->will($this->returnValue($specialPriceValue));
-        $this->assertSame($specialPriceValue, $this->basePrice->getValue());
+        $this->assertSame($expectedResult, $this->basePrice->getValue());
+    }
+
+    public function getValueDataProvider()
+    {
+        return array(array(77, 77), array(0, 0), array(false, 99));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
index e1293d81d92d8de43f262dcbc56fdb48ae6cbb10..4a9fc61ffaf771d2e7ad844752838ea1b18cdf3b 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Import/Product/Type/OptionTest.php
@@ -384,7 +384,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
             false
         );
 
-        $productModelMock = $this->getMock('stdClass', array('getProductEntitiesInfo'), array(), '', false);
+        $productModelMock = $this->getMock('stdClass', array('getProductEntitiesInfo'));
         $productModelMock->expects(
             $this->any()
         )->method(
@@ -884,7 +884,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
 
     public function testParseRequiredData()
     {
-        $modelData = $this->getMock('stdClass', array('getNextBunch'), array(), '', false);
+        $modelData = $this->getMock('stdClass', array('getNextBunch'));
         $modelData->expects(
             $this->at(0)
         )->method(
@@ -896,7 +896,7 @@ class OptionTest extends \PHPUnit_Framework_TestCase
         );
         $modelData->expects($this->at(1))->method('getNextBunch')->will($this->returnValue(null));
 
-        $productModel = $this->getMock('stdClass', array('getProductEntitiesInfo'), array(), '', false);
+        $productModel = $this->getMock('stdClass', array('getProductEntitiesInfo'));
         $productModel->expects($this->any())->method('getProductEntitiesInfo')->will($this->returnValue(array()));
 
         $productEntity = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/ImportTest.php b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/ImportTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3d45cf6ef127796a6e14a3176cbd378bb94e2692
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogImportExport/Model/Indexer/Stock/Plugin/ImportTest.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\CatalogImportExport\Model\Indexer\Stock\Plugin;
+
+class ImportTest extends \PHPUnit_Framework_TestCase
+{
+    public function testAfterImportSource()
+    {
+        /**
+         * @var \Magento\Catalog\Model\Indexer\Product\Flat\Processor|
+         *      \PHPUnit_Framework_MockObject_MockObject $processorMock
+         */
+        $processorMock = $this->getMock(
+            'Magento\CatalogInventory\Model\Indexer\Stock\Processor',
+            array('markIndexerAsInvalid'),
+            array(),
+            '',
+            false
+        );
+
+        $subjectMock = $this->getMock('Magento\ImportExport\Model\Import', array(), array(), '', false);
+        $processorMock->expects($this->once())->method('markIndexerAsInvalid');
+
+        $someData = array(1, 2, 3);
+
+        $model = new \Magento\CatalogImportExport\Model\Indexer\Stock\Plugin\Import($processorMock);
+        $this->assertEquals($someData, $model->afterImportSource($subjectMock, $someData));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f336727d622d937c5eb6278d85ee0cd96bc9a375
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/FullTest.php
@@ -0,0 +1,66 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+class FullTest extends \PHPUnit_Framework_TestCase
+{
+    public function testExecuteWithAdapterErrorThrowsException()
+    {
+        $indexerFactoryMock = $this->getMock(
+            'Magento\CatalogInventory\Model\Resource\Indexer\StockFactory',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $resourceMock = $this->getMock('Magento\Framework\App\Resource', array('getConnection'), array(), '', false);
+        $productTypeMock = $this->getMock('Magento\Catalog\Model\Product\Type', array(), array(), '', false);
+        $adapterMock = $this->getMock('Magento\Framework\DB\Adapter\AdapterInterface');
+
+        $exceptionMessage = 'exception message';
+        $exception = new \Exception($exceptionMessage);
+
+        $adapterMock->expects($this->once())
+            ->method('delete')
+            ->will($this->throwException($exception));
+
+        $resourceMock->expects($this->any())
+            ->method('getConnection')
+            ->will($this->returnValue($adapterMock));
+
+        $model = new \Magento\CatalogInventory\Model\Indexer\Stock\Action\Full(
+            $resourceMock,
+            $indexerFactoryMock,
+            $productTypeMock
+        );
+
+        $this->setExpectedException('\Magento\CatalogInventory\Exception', $exceptionMessage);
+
+        $model->execute();
+    }
+}
diff --git a/app/code/Magento/Tax/Service/V1/Data/SearchResults.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
similarity index 56%
rename from app/code/Magento/Tax/Service/V1/Data/SearchResults.php
rename to dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
index bab5597929d6e6206dbc848edd0b9f7a452a6ac4..fc0946e0a40e19a4c26af878f8f08c1637a1934d 100644
--- a/app/code/Magento/Tax/Service/V1/Data/SearchResults.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowTest.php
@@ -18,44 +18,36 @@
  * versions in the future. If you wish to customize Magento for your
  * needs please refer to http://www.magentocommerce.com for more information.
  *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @subpackage  unit_tests
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Tax\Service\V1\Data;
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
 
-/**
- * Data object for Tax class search results.
- */
-class SearchResults extends \Magento\Framework\Service\Data\AbstractObject
+use Magento\TestFramework\Helper\ObjectManager;
+
+class RowTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * Get list of tax classes.
-     *
-     * @return \Magento\Tax\Service\V1\Data\TaxClass[]
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows
      */
-    public function getItems()
-    {
-        return is_null($this->_get('items')) ? [] : $this->_get('items');
-    }
+    protected $_model;
 
-    /**
-     * Get search criteria.
-     *
-     * @return \Magento\Framework\Service\V1\Data\SearchCriteria
-     */
-    public function getSearchCriteria()
+    public function setUp()
     {
-        return $this->_get('search_criteria');
+        $objectManager = new ObjectManager($this);
+        $this->_model = $objectManager->getObject('Magento\CatalogInventory\Model\Indexer\Stock\Action\Row');
     }
 
     /**
-     * Get total count.
-     *
-     * @return int
+     * @expectedException \Magento\CatalogInventory\Exception
+     * @expectedExceptionMessage Could not rebuild index for undefined product
      */
-    public function getTotalCount()
+    public function testEmptyId()
     {
-        return $this->_get('total_count');
+        $this->_model->execute(null);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..075b27be5021ed63ec51fbaa82ce1481c62835f4
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Action/RowsTest.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Action;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+class RowsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows
+     */
+    protected $_model;
+
+    public function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->_model = $objectManager->getObject('Magento\CatalogInventory\Model\Indexer\Stock\Action\Rows');
+    }
+
+    /**
+     * @expectedException \Magento\CatalogInventory\Exception
+     * @expectedExceptionMessage Could not rebuild index for empty products array
+     */
+    public function testEmptyIds()
+    {
+        $this->_model->execute(null);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroupTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroupTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..572224114d114a68bb29fcb528e019d64c579f28
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Indexer/Stock/Plugin/StoreGroupTest.php
@@ -0,0 +1,108 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @category    Magento
+ * @package     Magento_CatalogInventory
+ * @subpackage  unit_tests
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\CatalogInventory\Model\Indexer\Stock\Plugin;
+
+class StoreGroupTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Plugin\StoreGroup
+     */
+    protected $_model;
+
+    /**
+     * @var \Magento\Indexer\Model\IndexerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_indexerMock;
+
+    public function setUp()
+    {
+        $this->_indexerMock = $this->getMock(
+            '\Magento\CatalogInventory\Model\Indexer\Stock\Processor',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $this->_model = new \Magento\CatalogInventory\Model\Indexer\Stock\Plugin\StoreGroup($this->_indexerMock);
+    }
+
+    /**
+     * @param array $data
+     * @dataProvider beforeSaveDataProvider
+     */
+    public function testBeforeSave(array $data)
+    {
+        $subjectMock = $this->getMock('Magento\Store\Model\Resource\Group', array(), array(), '', false);
+        $objectMock = $this->getMock(
+            'Magento\Framework\Model\AbstractModel',
+            array('getId', 'dataHasChangedFor', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+        $objectMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue($data['object_id']));
+        $objectMock->expects($this->any())
+            ->method('dataHasChangedFor')
+            ->with('website_id')
+            ->will($this->returnValue($data['has_website_id_changed']));
+
+        $this->_indexerMock->expects($this->once())
+            ->method('markIndexerAsInvalid');
+
+        $this->_model->beforeSave($subjectMock, $objectMock);
+    }
+
+    /**
+     * @return array
+     */
+    public function beforeSaveDataProvider()
+    {
+        return array(
+            array(
+                array(
+                    'object_id' => 1,
+                    'has_website_id_changed' => true
+                )
+            ),
+            array(
+                array(
+                    'object_id' => false,
+                    'has_website_id_changed' => true
+                )
+            ),
+            array(
+                array(
+                    'object_id' => false,
+                    'has_website_id_changed' => false
+                )
+            ),
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php
index 02cbeeaaa1b65e04f1d7c964a12371d333e74cfa..1494652bbc1a599b594b857c30b97b6d50f0eee3 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/ObserverTest.php
@@ -58,20 +58,55 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
      */
     protected $event;
 
+    /**
+     * @var \Magento\CatalogInventory\Helper\Data |\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $catalogInventoryData;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Stock | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $stock;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Indexer\Stock\Processor | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $stockIndexProcessor;
+
+    /**
+     * @var \Magento\Catalog\Model\Indexer\Product\Price\Processor | \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $priceIndexer;
+
     protected function setUp()
     {
         $this->stockItemRegistry = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\ItemRegistry')
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->stockStatus = $this->getMockBuilder('Magento\CatalogInventory\Model\Stock\Status')
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->stockFactory = $this->getMockBuilder('Magento\CatalogInventory\Model\StockFactory')
             ->setMethods(['create'])
             ->getMock();
 
+        $this->catalogInventoryData = $this->getMock('Magento\CatalogInventory\Helper\Data', [], [], '', false);
+        $this->stock = $this->getMock('Magento\CatalogInventory\Model\Stock', [], [], '', false);
+        $this->stockIndexProcessor = $this->getMock(
+            '\Magento\Catalog\Model\Indexer\Product\Stock\Processor',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->priceIndexer = $this->getMock(
+            '\Magento\Catalog\Model\Indexer\Product\Price\Processor',
+            [],
+            [],
+            '',
+            false
+        );
+
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->model = $objectManagerHelper->getObject(
             'Magento\CatalogInventory\Model\Observer',
@@ -84,7 +119,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
 
         $this->event = $this->getMockBuilder('Magento\Framework\Event')
             ->disableOriginalConstructor()
-            ->setMethods(['getProduct', 'getCollection'])
+            ->setMethods(['getProduct', 'getCollection', 'getCreditmemo'])
             ->getMock();
 
         $this->eventObserver = $this->getMockBuilder('Magento\Framework\Event\Observer')
@@ -194,4 +229,43 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($this->model, $this->model->addStockStatusToCollection($this->eventObserver));
     }
+
+    public function refundOrderInventory()
+    {
+        $ids = ['1', '14'];
+        $items = [];
+        foreach ($ids as $id) {
+            $items[] = $this->getCreditMemoItem($id);
+        }
+        $creditMemo = $this->getMock('Magento\Sales\Model\Order\Creditmemo', [], [], '', false);
+        $creditMemo->expects($this->once())
+            ->method('getAllItems')
+            ->will($this->returnValue($items));
+
+        $this->event->expects($this->once())
+            ->method('getCreditmemo')
+            ->will($this->returnValue($creditMemo));
+
+        $this->catalogInventoryData->expects($this->once())
+            ->method('isAutoReturnEnabled')
+            ->will($this->returnValue(true));
+
+        $this->stock->expects($this->once())
+            ->method('revertProductsSale')
+            ->with($items);
+        $this->stockIndexProcessor->expects($this->once())
+            ->method('reidexList')
+            ->with($ids);
+
+        $this->model->refundOrderInventory($this->eventObserver);
+    }
+
+    private function getCreditMemoItem($productId)
+    {
+        $item = $this->getMock('Magento\Sales\Model\Order\Creditmemo\Item', [], [], '', false);
+        $item->expects($this->once())
+            ->method('getProductId')
+            ->will($this->returnValue($productId));
+        return $item;
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php
index 7f60919b7a2eb57821a8420822fc3ffd70ecf14e..25bbf5ecac298d6fa58ffa5bdbeace746d1f587f 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogInventory/Model/Stock/ItemTest.php
@@ -675,4 +675,22 @@ class ItemTest extends \PHPUnit_Framework_TestCase
     {
         $this->assertSame(1, $this->item->getStockId());
     }
+
+    public function testProcessIsInStock()
+    {
+        $this->item->setData(
+            [
+                'qty' => 100,
+                'is_in_stock' => \Magento\CatalogInventory\Model\Stock\Status::STATUS_IN_STOCK,
+                'manage_stock' => 1,
+                'use_config_manage_stock' => 0
+            ]
+        );
+        $this->item->setData('qty', 0);
+        $this->item->processIsInStock();
+        $this->assertEquals(
+            \Magento\CatalogInventory\Model\Stock\Status::STATUS_OUT_OF_STOCK,
+            $this->item->getIsInStock()
+        );
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/CatalogRule/Model/RuleTest.php b/dev/tests/unit/testsuite/Magento/CatalogRule/Model/RuleTest.php
index 7d251ad3cbab31b607a8aea8f611b7d4e7331a17..a8420516f5d3fa18c9be8a41ba9a493d94750d5a 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogRule/Model/RuleTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogRule/Model/RuleTest.php
@@ -101,7 +101,6 @@ class RuleTest extends \PHPUnit_Framework_TestCase
     }
 
     /**
-     * @covers _getWebsitesMap
      * @dataProvider dataProviderCallbackValidateProduct
      * @param bool $validate
      */
diff --git a/dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/AdvancedTest.php b/dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/Advanced/ResultTest.php
similarity index 90%
rename from dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/AdvancedTest.php
rename to dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/Advanced/ResultTest.php
index 32229adf2386cbab8d729a95a12004377439f3c1..91671de7e93ae9a8912eb97923b20f6a446d3308 100644
--- a/dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/AdvancedTest.php
+++ b/dev/tests/unit/testsuite/Magento/CatalogSearch/Controller/Advanced/ResultTest.php
@@ -21,9 +21,9 @@
  * @copyright Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\CatalogSearch\Controller;
+namespace Magento\CatalogSearch\Controller\Advanced;
 
-class AdvancedTest extends \PHPUnit_Framework_TestCase
+class ResultTest extends \PHPUnit_Framework_TestCase
 {
     public function testResultActionFiltersSetBeforeLoadLayout()
     {
@@ -63,11 +63,11 @@ class AdvancedTest extends \PHPUnit_Framework_TestCase
             array('view' => $view, 'request' => $request)
         );
 
-        /** @var \Magento\CatalogSearch\Controller\Advanced $instance */
+        /** @var \Magento\CatalogSearch\Controller\Advanced\Result $instance */
         $instance = $objectManager->getObject(
-            'Magento\CatalogSearch\Controller\Advanced',
+            'Magento\CatalogSearch\Controller\Advanced\Result',
             array('context' => $context, 'catalogSearchAdvanced' => $catalogSearchAdvanced)
         );
-        $instance->resultAction();
+        $instance->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Helper/CartTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Helper/CartTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4792118e686ddd7df1c793b04e068ee5aa52f988
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Helper/CartTest.php
@@ -0,0 +1,209 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Checkout\Helper;
+
+use \Magento\Framework\App\Action\Action;
+use \Magento\Framework\Object;
+
+class CartTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cartMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $checkoutSessionMock;
+
+    /**
+     * @var Cart
+     */
+    protected $helper;
+
+    protected function setUp()
+    {
+        $this->urlBuilderMock = $this->getMock('\Magento\Framework\UrlInterface');
+        $this->requestMock = $this->getMock(
+            '\Magento\Framework\App\RequestInterface',
+            array(
+                'getRouteName',
+                'getControllerName',
+                'getParam',
+                'setActionName',
+                'getActionName',
+                'setModuleName',
+                'getModuleName',
+            )
+        );
+        $contextMock = $this->getMock('\Magento\Framework\App\Helper\Context', [], [], '', false);
+        $contextMock->expects($this->any())->method('getUrlBuilder')->will($this->returnValue($this->urlBuilderMock));
+        $contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->requestMock));
+        $this->storeManagerMock = $this->getMock('\Magento\Store\Model\StoreManagerInterface');
+        $this->coreHelperMock = $this->getMock('\Magento\Core\Helper\Data', [], [], '', false);
+        $this->scopeConfigMock = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
+        $this->cartMock = $this->getMock('\Magento\Checkout\Model\Cart', [], [], '', false);
+        $this->checkoutSessionMock = $this->getMock('\Magento\Checkout\Model\Session', [], [], '', false);
+
+        $this->helper = new Cart(
+            $contextMock,
+            $this->storeManagerMock,
+            $this->coreHelperMock,
+            $this->scopeConfigMock,
+            $this->cartMock,
+            $this->checkoutSessionMock
+        );
+
+    }
+
+    public function testGetCart()
+    {
+        $this->assertEquals($this->cartMock, $this->helper->getCart());
+    }
+
+    public function testGetRemoveUrl()
+    {
+        $quoteItemId = 1;
+        $quoteItemMock = $this->getMock('\Magento\Sales\Model\Quote\Item', [], [], '', false);
+        $quoteItemMock->expects($this->any())->method('getId')->will($this->returnValue($quoteItemId));
+        $currentUrl = 'http://www.example.com/';
+        $this->urlBuilderMock->expects($this->any())->method('getCurrentUrl')->will($this->returnValue($currentUrl));
+        $params = array(
+            'id' => $quoteItemId,
+            Action::PARAM_NAME_BASE64_URL => strtr(base64_encode($currentUrl), '+/=', '-_,'),
+        );
+        $this->urlBuilderMock->expects($this->once())->method('getUrl')->with('checkout/cart/delete', $params);
+        $this->helper->getRemoveUrl($quoteItemMock);
+    }
+
+    public function testGetCartUrl()
+    {
+        $this->urlBuilderMock->expects($this->once())->method('getUrl')->with('checkout/cart', array());
+        $this->helper->getCartUrl();
+    }
+
+    public function testGetQuote()
+    {
+        $quoteMock = $this->getMock('\Magento\Sales\Model\Quote', [], [], '', false);
+        $this->checkoutSessionMock->expects($this->once())->method('getQuote')->will($this->returnValue($quoteMock));
+        $this->assertEquals($quoteMock, $this->helper->getQuote());
+    }
+
+    public function testGetItemsCount()
+    {
+        $itemsCount = 1;
+        $this->cartMock->expects($this->any())->method('getItemsCount')->will($this->returnValue($itemsCount));
+        $this->assertEquals($itemsCount, $this->helper->getItemsCount());
+    }
+
+    public function testGetItemsQty()
+    {
+        $itemsQty = 1;
+        $this->cartMock->expects($this->any())->method('getItemsQty')->will($this->returnValue($itemsQty));
+        $this->assertEquals($itemsQty, $this->helper->getItemsQty());
+    }
+
+    public function testGetSummaryCount()
+    {
+        $summaryQty = 1;
+        $this->cartMock->expects($this->any())->method('getSummaryQty')->will($this->returnValue($summaryQty));
+        $this->assertEquals($summaryQty, $this->helper->getSummaryCount());
+    }
+
+    public function testGetIsVirtualQuote()
+    {
+        $isVirtual = true;
+        $quoteMock = $this->getMock('\Magento\Sales\Model\Quote', [], [], '', false);
+        $this->checkoutSessionMock->expects($this->once())->method('getQuote')->will($this->returnValue($quoteMock));
+        $quoteMock->expects($this->any())->method('isVirtual')->will($this->returnValue($isVirtual));
+        $this->assertEquals($isVirtual, $this->helper->getIsVirtualQuote());
+    }
+
+    public function testGetShouldRedirectToCart()
+    {
+        $storeId = 1;
+        $this->scopeConfigMock->expects($this->once())->method('isSetFlag')
+            ->with(Cart::XML_PATH_REDIRECT_TO_CART, \Magento\Store\Model\ScopeInterface::SCOPE_STORE, $storeId)
+            ->will($this->returnValue(true));
+        $this->assertTrue($this->helper->getShouldRedirectToCart($storeId));
+    }
+
+    public function testGetAddUrl()
+    {
+        $productEntityId = 1;
+        $storeId = 1;
+        $productMock = $this->getMock('\Magento\Catalog\Model\Product',
+            ['getEntityId', 'hasUrlDataObject', 'getUrlDataObject', '__wakeup'], [], '', false);
+        $productMock->expects($this->any())->method('getEntityId')->will($this->returnValue($productEntityId));
+        $productMock->expects($this->any())->method('hasUrlDataObject')->will($this->returnValue(true));
+        $productMock->expects($this->any())->method('getUrlDataObject')
+            ->will($this->returnValue(new Object(array('store_id' => $storeId))));
+
+        $currentUrl = 'http://www.example.com/';
+        $this->urlBuilderMock->expects($this->any())->method('getCurrentUrl')->will($this->returnValue($currentUrl));
+        $this->coreHelperMock->expects($this->any())->method('urlEncode')->with($currentUrl)
+            ->will($this->returnValue($currentUrl));
+
+        $this->requestMock->expects($this->any())->method('getRouteName')->will($this->returnValue('checkout'));
+        $this->requestMock->expects($this->any())->method('getControllerName')->will($this->returnValue('cart'));
+
+        $params = array(
+            Action::PARAM_NAME_URL_ENCODED => $currentUrl,
+            'product' => $productEntityId,
+            'custom_param' => 'value',
+            '_scope' => $storeId,
+            '_scope_to_url' => true,
+            'in_cart' => 1,
+        );
+
+        $this->urlBuilderMock->expects($this->once())->method('getUrl')->with('checkout/cart/add', $params);
+        $this->helper->getAddUrl($productMock, array('custom_param' => 'value'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
index e1c795c886e23f329e2d82c49d1a3f2d2391f63e..54ee89203cbd91befd8629a3393b55281b2130f9 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/CartTest.php
@@ -40,12 +40,24 @@ class CartTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Checkout\Model\Session|\PHPUnit_Framework_MockObject_MockObject */
     protected $checkoutSessionMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerSessionMock;
+
     /** @var \Magento\CatalogInventory\Service\V1\StockItemService|\PHPUnit_Framework_MockObject_MockObject */
     protected $stockItemMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
     protected function setUp()
     {
         $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false);
+        $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', [], [], '', false);
+        $this->scopeConfigMock = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface');
         $this->stockItemMock = $this->getMock(
             'Magento\CatalogInventory\Service\V1\StockItemService',
             [],
@@ -58,8 +70,10 @@ class CartTest extends \PHPUnit_Framework_TestCase
         $this->cart = $this->objectManagerHelper->getObject(
             'Magento\Checkout\Model\Cart',
             [
+                'scopeConfig' => $this->scopeConfigMock,
                 'checkoutSession' => $this->checkoutSessionMock,
-                'stockItemService' => $this->stockItemMock
+                'stockItemService' => $this->stockItemMock,
+                'customerSession' => $this->customerSessionMock,
             ]
         );
     }
@@ -131,4 +145,42 @@ class CartTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($product));
         return $quoteItem;
     }
+
+    /**
+     * @param boolean $useQty
+     * @dataProvider useQtyDataProvider
+     */
+    public function testGetSummaryQty($useQty)
+    {
+        $quoteId = 1;
+        $itemsCount = 1;
+        $quoteMock = $this->getMock(
+            'Magento\Sales\Model\Quote',
+            ['getItemsCount', 'getItemsQty', '__wakeup'],
+            [],
+            '',
+            false
+        );
+
+        $this->checkoutSessionMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock));
+        $this->checkoutSessionMock->expects($this->at(2))->method('getQuoteId')->will($this->returnValue($quoteId));
+        $this->customerSessionMock->expects($this->any())->method('isLoggedIn')->will($this->returnValue(true));
+
+        $this->scopeConfigMock->expects($this->once())->method('getValue')
+            ->with('checkout/cart_link/use_qty', \Magento\Store\Model\ScopeInterface::SCOPE_STORE)
+            ->will($this->returnValue($useQty));
+
+        $qtyMethodName = ($useQty) ? 'getItemsQty' : 'getItemsCount';
+        $quoteMock->expects($this->once())->method($qtyMethodName)->will($this->returnValue($itemsCount));
+
+        $this->assertEquals($itemsCount, $this->cart->getSummaryQty());
+    }
+
+    public function useQtyDataProvider()
+    {
+        return [
+            ['useQty' => true],
+            ['useQty' => false]
+        ];
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/RecurringPayment/Controller/RecurringPaymentTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/Config/Source/Cart/SummaryTest.php
similarity index 66%
rename from dev/tests/unit/testsuite/Magento/RecurringPayment/Controller/RecurringPaymentTest.php
rename to dev/tests/unit/testsuite/Magento/Checkout/Model/Config/Source/Cart/SummaryTest.php
index 5c751bd5b53121b287d5dfb3028a0d98584db6fa..9901a311bddf345c820174a26eba0148dc51b714 100644
--- a/dev/tests/unit/testsuite/Magento/RecurringPayment/Controller/RecurringPaymentTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/Config/Source/Cart/SummaryTest.php
@@ -21,23 +21,26 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\RecurringPayment\Controller;
+namespace Magento\Checkout\Model\Config\Source\Cart;
 
-class RecurringPaymentTest extends \PHPUnit_Framework_TestCase
+class SummaryTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\RecurringPayment\Controller\RecurringPayment
+     * @var Summary
      */
-    protected $_controller;
+    private $model;
 
     protected function setUp()
     {
-        $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_controller = $objectHelper->getObject('Magento\RecurringPayment\Controller\RecurringPayment');
+        $this->model = new Summary();
     }
 
-    public function testOrdersAction()
+    public function testToOptionArray()
     {
-        $this->assertTrue(method_exists($this->_controller, 'ordersAction'));
+        $expectedResult = array(
+            array('value' => 0, 'label' => __('Display number of items in cart')),
+            array('value' => 1, 'label' => __('Display item quantities'))
+        );
+        $this->assertEquals($expectedResult, $this->model->toOptionArray());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
index 4c86ada75aa412c915ac7c473efaf8068bb993e0..ea5e864eba9b16fdbaa5ba0339165ca55382a870 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/SessionTest.php
@@ -356,4 +356,63 @@ class SessionTest extends \PHPUnit_Framework_TestCase
         $this->assertInstanceOf('Magento\Checkout\Model\Session', $session->clearStorage());
         $this->assertFalse($session->hasQuote());
     }
+
+    public function testResetCheckout()
+    {
+        /** @var $session \Magento\Checkout\Model\Session */
+        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', array(
+            'storage' => new \Magento\Framework\Session\Storage()
+        ));
+        $session->resetCheckout();
+        $this->assertEquals(\Magento\Checkout\Model\Session::CHECKOUT_STATE_BEGIN, $session->getCheckoutState());
+    }
+
+    public function testGetStepData()
+    {
+        $stepData = array(
+            'simple' => 'data',
+            'complex' => array(
+                'key' => 'value',
+            ),
+        );
+        /** @var $session \Magento\Checkout\Model\Session */
+        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', array(
+            'storage' => new \Magento\Framework\Session\Storage()
+        ));
+        $session->setSteps($stepData);
+        $this->assertEquals($stepData, $session->getStepData());
+        $this->assertFalse($session->getStepData('invalid_key'));
+        $this->assertEquals($stepData['complex'], $session->getStepData('complex'));
+        $this->assertFalse($session->getStepData('simple', 'invalid_sub_key'));
+        $this->assertEquals($stepData['complex']['key'], $session->getStepData('complex', 'key'));
+    }
+
+    public function testSetStepData()
+    {
+        $stepData = array(
+            'complex' => array(
+                'key' => 'value',
+            ),
+        );
+        /** @var $session \Magento\Checkout\Model\Session */
+        $session = $this->_helper->getObject('\Magento\Checkout\Model\Session', array(
+            'storage' => new \Magento\Framework\Session\Storage()
+        ));
+        $session->setSteps($stepData);
+
+        $session->setStepData('complex', 'key2', 'value2');
+        $session->setStepData('simple', array('key' => 'value'));
+        $session->setStepData('simple', 'key2', 'value2');
+        $expectedResult = array(
+            'complex' => array(
+                'key' => 'value',
+                'key2' => 'value2',
+            ),
+            'simple' => array(
+                'key' => 'value',
+                'key2' => 'value2',
+            ),
+        );
+        $this->assertEquals($expectedResult, $session->getSteps());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php b/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
index dd38363a390dfb43e6149b2e7d2b957027234bfe..37aab269fdf758750eec1aacb81ff0c7369695d6 100644
--- a/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Checkout/Model/Type/OnepageTest.php
@@ -110,7 +110,8 @@ class OnepageTest extends \PHPUnit_Framework_TestCase
         $this->checkoutHelperMock = $this->getMock('Magento\Checkout\Helper\Data', [], [], '', false);
         $this->customerHelperMock = $this->getMock('Magento\Customer\Helper\Data', [], [], '', false);
         $this->loggerMock = $this->getMock('Magento\Framework\Logger', [], [], '', false);
-        $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session', [], [], '', false);
+        $this->checkoutSessionMock = $this->getMock('Magento\Checkout\Model\Session',
+            ['getLastOrderId', 'getQuote', 'setStepData', 'getStepData'], [], '', false);
         $this->customerSessionMock = $this->getMock('Magento\Customer\Model\Session', [], [], '', false);
         $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManagerInterface');
         $this->requestMock = $this->getMock(
@@ -121,7 +122,7 @@ class OnepageTest extends \PHPUnit_Framework_TestCase
         $this->formFactoryMock = $this->getMock('Magento\Customer\Model\FormFactory');
         $this->customerFactoryMock = $this->getMock('Magento\Customer\Model\CustomerFactory');
         $this->quoteFactoryMock = $this->getMock('Magento\Sales\Model\Service\QuoteFactory');
-        $this->orderFactoryMock = $this->getMock('Magento\Sales\Model\OrderFactory');
+        $this->orderFactoryMock = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
         $this->copyMock = $this->getMock('Magento\Framework\Object\Copy', [], [], '', false);
         $this->messageManagerMock = $this->getMock('Magento\Framework\Message\ManagerInterface');
 
@@ -469,4 +470,17 @@ class OnepageTest extends \PHPUnit_Framework_TestCase
             ]
         ];
     }
+
+    public function testGetLastOrderId()
+    {
+        $orderIncrementId = 100001;
+        $orderId = 1;
+        $this->checkoutSessionMock->expects($this->once())->method('getLastOrderId')
+            ->will($this->returnValue($orderId));
+        $orderMock = $this->getMock('Magento\Sales\Model\Order', ['load', 'getIncrementId', '__wakeup'], [], '', false);
+        $orderMock->expects($this->once())->method('load')->with($orderId)->will($this->returnSelf());
+        $orderMock->expects($this->once())->method('getIncrementId')->will($this->returnValue($orderIncrementId));
+        $this->orderFactoryMock->expects($this->once())->method('create')->will($this->returnValue($orderMock));
+        $this->assertEquals($orderIncrementId, $this->onepage->getLastOrderId());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Cms/Controller/NorouteTest.php b/dev/tests/unit/testsuite/Magento/Cms/Controller/NorouteTest.php
index a30693834b879a11d23eaf65c8c5958117d6ff60..0d03f7d24a032ab984bfd8a2640481602efcf9ae 100644
--- a/dev/tests/unit/testsuite/Magento/Cms/Controller/NorouteTest.php
+++ b/dev/tests/unit/testsuite/Magento/Cms/Controller/NorouteTest.php
@@ -88,7 +88,7 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('pageId')
         );
         $this->_controller = $helper->getObject(
-            'Magento\Cms\Controller\Noroute',
+            'Magento\Cms\Controller\Noroute\Index',
             array('response' => $responseMock, 'objectManager' => $objectManagerMock, 'request' => $this->_requestMock)
         );
     }
@@ -101,7 +101,7 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
     {
         $this->_cmsHelperMock->expects($this->once())->method('renderPage')->will($this->returnValue($renderPage));
         $this->_requestMock->expects($this->any())->method('setActionName')->with('defaultNoRoute');
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function indexActionDataProvider()
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelectorTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelectorTest.php
index 54817034e6d9c113ec0bd56ed79841cc4547649b..0fed2526b6e83bc854e47604f463cabadc69a45e 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelectorTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AttributeSelectorTest.php
@@ -67,7 +67,7 @@ class AttributeSelectorTest extends \PHPUnit_Framework_TestCase
         )->method(
             'getUrl'
         )->with(
-            '*/product_attribute_suggestConfigurableAttributes'
+            '*/product_attribute/suggestConfigurableAttributes'
         )->will(
             $this->returnValue($source)
         );
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php
index 3170cf72a6edc4014a84c3091a9e6bcc3ed8aba2..dc1c7603cb931f0f16f7fa6aca296547db1ddbd8 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Attribute/SuggestConfigurableAttributesTest.php
@@ -105,6 +105,6 @@ class SuggestConfigurableAttributesTest extends \PHPUnit_Framework_TestCase
             $this->returnValue('body')
         );
         $this->responseMock->expects($this->once())->method('representJson')->with('body');
-        $this->suggestAttributes->indexAction();
+        $this->suggestAttributes->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
index 8e7f8fa222fb21b3e404b65cb040b5ef1f3aac40..53e459fceebed62c1594a18b5157fdb0b929c907 100644
--- a/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/ConfigurableProduct/Pricing/Price/AttributePriceTest.php
@@ -366,9 +366,10 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase
             'showBothPrices' => false,
             'defaultTax' => 0,
             'currentTax' => 0,
-            'inclTaxTitle' => __('Incl. Tax')
+            'inclTaxTitle' => __('Incl. Tax'),
+            'customerId' => 1
         ];
-        $this->assertEquals($expectedTaxConfig, $this->attribute->getTaxConfig());
+        $this->assertEquals($expectedTaxConfig, $this->attribute->getTaxConfig(1));
     }
 
     /**
@@ -383,8 +384,9 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase
             'defaultTax' => 0,
             'currentTax' => 0,
             'inclTaxTitle' => __('Incl. Tax'),
-            'product' => $this->saleableItemMock
+            'product' => $this->saleableItemMock,
+            'customerId' => 1
         ];
-        $this->assertEquals($expectedAdjustmentConfig, $this->attribute->prepareAdjustmentConfig());
+        $this->assertEquals($expectedAdjustmentConfig, $this->attribute->prepareAdjustmentConfig(1));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Core/Controller/NorouteTest.php b/dev/tests/unit/testsuite/Magento/Core/Controller/NorouteTest.php
index 6b384715d0831d4d63a95e0c116b0ff797593cf1..513413e9bb3887fab3b6a3d32cd9092c531742e2 100644
--- a/dev/tests/unit/testsuite/Magento/Core/Controller/NorouteTest.php
+++ b/dev/tests/unit/testsuite/Magento/Core/Controller/NorouteTest.php
@@ -52,7 +52,7 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
         $this->_viewMock = $this->getMock('\Magento\Framework\App\ViewInterface');
         $this->_statusMock = $this->getMock('Magento\Framework\Object', array('getLoaded'), array(), '', false);
         $this->_controller = $helper->getObject(
-            'Magento\Core\Controller\Noroute',
+            'Magento\Core\Controller\Noroute\Index',
             array('request' => $this->_requestMock, 'view' => $this->_viewMock)
         );
     }
@@ -71,7 +71,7 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
         $this->_statusMock->expects($this->any())->method('getLoaded')->will($this->returnValue(false));
         $this->_viewMock->expects($this->once())->method('loadLayout')->with(array('default', 'noroute'));
         $this->_viewMock->expects($this->once())->method('renderLayout');
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionWhenStatusLoaded()
@@ -95,7 +95,7 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue($this->_requestMock)
         );
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 
     public function testIndexActionWhenStatusNotInstanceofMagentoObject()
@@ -109,6 +109,6 @@ class NorouteTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue('string')
         );
-        $this->_controller->indexAction();
+        $this->_controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Cron/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/Cron/Model/ObserverTest.php
index b613b427f8dab595f0c925a150454f44ff6963ce..b32a48b01723b884d1b12c2d65b88b56acaacca8 100644
--- a/dev/tests/unit/testsuite/Magento/Cron/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/Cron/Model/ObserverTest.php
@@ -454,7 +454,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         )->method(
             'load'
         )->with(
-            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT)
+            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT . 'test_group')
         )->will(
             $this->returnValue(time() - 10000000)
         );
@@ -463,7 +463,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         )->method(
             'load'
         )->with(
-            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_HISTORY_CLEANUP_AT)
+            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_HISTORY_CLEANUP_AT . 'test_group')
         )->will(
             $this->returnValue(time() + 10000000)
         );
@@ -525,7 +525,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         )->method(
             'load'
         )->with(
-            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT)
+            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_SCHEDULE_GENERATE_AT . 'test_group')
         )->will(
             $this->returnValue(time() - 10000000)
         );
@@ -534,7 +534,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         )->method(
             'load'
         )->with(
-            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_HISTORY_CLEANUP_AT)
+            $this->equalTo(\Magento\Cron\Model\Observer::CACHE_KEY_LAST_HISTORY_CLEANUP_AT . 'test_group')
         )->will(
             $this->returnValue(time() + 10000000)
         );
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreatePostTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreatePostTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..02e30e8900ca09c77e5c56822ed41f935fa38c75
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreatePostTest.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class CreatePostTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Customer\Controller\Account\CreatePost
+     */
+    protected $object;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerSession;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $redirectMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $accountServiceMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->customerSession = $this->getMock('\Magento\Customer\Model\Session', [], [], '', false);
+        $this->customerHelperMock = $this->getMock('\Magento\Customer\Helper\Data', [], [], '', false);
+        $this->redirectMock = $this->getMock('Magento\Framework\App\Response\RedirectInterface');
+        $this->accountServiceMock = $this->getMock('Magento\Customer\Service\V1\CustomerAccountServiceInterface');
+        $this->response = $this->getMock('Magento\Framework\App\ResponseInterface');
+        $this->object = $objectManager->getObject('Magento\Customer\Controller\Account\CreatePost',
+            [
+                'response' => $this->response,
+                'customerSession' => $this->customerSession,
+                'customerHelperData' => $this->customerHelperMock,
+                'redirect' => $this->redirectMock,
+                'customerAccountService' => $this->accountServiceMock,
+            ]
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreatePostActionRegistrationDisabled()
+    {
+        $this->customerSession->expects($this->once())
+            ->method('isLoggedIn')
+            ->will($this->returnValue(false));
+
+        $this->customerHelperMock->expects($this->once())
+            ->method('isRegistrationAllowed')
+            ->will($this->returnValue(false));
+
+        $this->redirectMock->expects($this->once())
+            ->method('redirect')
+            ->with($this->response, '*/*/', array())
+            ->will($this->returnValue(false));
+
+        $this->accountServiceMock->expects($this->never())
+            ->method('createCustomer');
+
+        $this->object->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreateTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..da09c3e82d2c0f16bd9285764e2d08d5dfa482b9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/CreateTest.php
@@ -0,0 +1,153 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Account;
+
+class CreateTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Customer\Controller\Account\Create
+     */
+    protected $object;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerSession;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerHelperMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $redirectMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $response;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    protected function setUp()
+    {
+        $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->customerSession = $this->getMock('\Magento\Customer\Model\Session', [], [], '', false);
+        $this->customerHelperMock = $this->getMock('\Magento\Customer\Helper\Data', [], [], '', false);
+        $this->redirectMock = $this->getMock('Magento\Framework\App\Response\RedirectInterface');
+        $this->response = $this->getMock('Magento\Framework\App\ResponseInterface');
+        $this->request = $this->getMock(
+            'Magento\Framework\App\RequestInterface',
+            array('isPost', 'getModuleName', 'setModuleName', 'getActionName', 'setActionName', 'getParam'),
+            array(),
+            '',
+            false
+        );
+        $this->viewMock = $this->getMock('Magento\Framework\App\ViewInterface');
+        $this->object = $objectManager->getObject('Magento\Customer\Controller\Account\Create',
+            [
+                'view' => $this->viewMock,
+                'request' => $this->request,
+                'response' => $this->response,
+                'customerSession' => $this->customerSession,
+                'customerHelper' => $this->customerHelperMock,
+                'redirect' => $this->redirectMock,
+            ]
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreateActionRegistrationDisabled()
+    {
+        $this->customerSession->expects($this->once())
+            ->method('isLoggedIn')
+            ->will($this->returnValue(false));
+
+        $this->customerHelperMock->expects($this->once())
+            ->method('isRegistrationAllowed')
+            ->will($this->returnValue(false));
+
+        $this->redirectMock->expects($this->once())
+            ->method('redirect')
+            ->with($this->response, '*/*', array())
+            ->will($this->returnValue(false));
+
+        $this->viewMock->expects($this->never())
+            ->method('loadLayout');
+        $this->viewMock->expects($this->never())
+            ->method('getLayout');
+        $this->viewMock->expects($this->never())
+            ->method('renderLayout');
+
+        $this->object->execute();
+    }
+
+    /**
+     * @return void
+     */
+    public function testCreateActionRegistrationEnabled()
+    {
+        $this->customerSession->expects($this->once())
+            ->method('isLoggedIn')
+            ->will($this->returnValue(false));
+
+        $this->customerHelperMock->expects($this->once())
+            ->method('isRegistrationAllowed')
+            ->will($this->returnValue(true));
+
+        $this->redirectMock->expects($this->never())
+            ->method('redirect');
+
+        $layoutMock = $this->getMock(
+            'Magento\Framework\View\Layout',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $layoutMock->expects($this->once())
+            ->method('initMessages')
+            ->will($this->returnSelf());
+
+        $this->viewMock->expects($this->once())
+            ->method('loadLayout')
+            ->will($this->returnSelf());
+        $this->viewMock->expects($this->once())
+            ->method('getLayout')
+            ->will($this->returnValue($layoutMock));
+        $this->viewMock->expects($this->once())
+            ->method('renderLayout')
+            ->will($this->returnSelf());
+
+        $this->object->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/AccountTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/LoginPostTest.php
similarity index 71%
rename from dev/tests/unit/testsuite/Magento/Customer/Controller/AccountTest.php
rename to dev/tests/unit/testsuite/Magento/Customer/Controller/Account/LoginPostTest.php
index 7e9d412e3c1e715dc42a040896ca4fd6f5dff606..d0d24fe76c1259ef38094ca2466389e39d9e30bc 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Controller/AccountTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Account/LoginPostTest.php
@@ -25,12 +25,12 @@
 /**
  * Test customer account controller
  */
-namespace Magento\Customer\Controller;
+namespace Magento\Customer\Controller\Account;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class AccountTest extends \PHPUnit_Framework_TestCase
+class LoginPostTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Customer\Controller\Account
@@ -130,7 +130,7 @@ class AccountTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->url = $this->getMockForAbstractClass('\Magento\Framework\UrlInterface');
+        $this->url = $this->getMock('\Magento\Framework\UrlInterface');
         $this->objectManager = $this->getMock(
             '\Magento\Framework\ObjectManager\ObjectManager',
             array('get'),
@@ -166,19 +166,18 @@ class AccountTest extends \PHPUnit_Framework_TestCase
 
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->object = $objectManager->getObject(
-            'Magento\Customer\Controller\Account',
+            'Magento\Customer\Controller\Account\LoginPost',
             array(
-                'request' => $this->request,
-                'response' => $this->response,
                 'customerSession' => $this->customerSession,
                 'url' => $this->url,
+                'request' => $this->request,
+                'response' => $this->response,
                 'objectManager' => $this->objectManager,
                 'formKeyValidator' => $this->_formKeyValidator,
                 'customerHelperData' => $this->customerHelperMock,
                 'redirect' => $this->redirectMock,
                 'view' => $this->viewMock,
                 'customerAccountService' => $this->customerAccountServiceMock,
-                ''
             )
         );
     }
@@ -233,98 +232,6 @@ class AccountTest extends \PHPUnit_Framework_TestCase
         );
         $this->url->expects($this->once())->method('isOwnOriginUrl')->with();
 
-        $this->object->loginPostAction();
-    }
-
-    /**
-     * @return void
-     */
-    public function testCreateActionRegistrationDisabled()
-    {
-        $this->customerSession->expects($this->once())
-            ->method('isLoggedIn')
-            ->will($this->returnValue(false));
-
-        $this->customerHelperMock->expects($this->once())
-            ->method('isRegistrationAllowed')
-            ->will($this->returnValue(false));
-
-        $this->redirectMock->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/*', array())
-            ->will($this->returnValue(false));
-
-        $this->viewMock->expects($this->never())
-            ->method('loadLayout');
-        $this->viewMock->expects($this->never())
-            ->method('getLayout');
-        $this->viewMock->expects($this->never())
-            ->method('renderLayout');
-
-        $this->object->createAction();
-    }
-
-    /**
-     * @return void
-     */
-    public function testCreateActionRegistrationEnabled()
-    {
-        $this->customerSession->expects($this->once())
-            ->method('isLoggedIn')
-            ->will($this->returnValue(false));
-
-        $this->customerHelperMock->expects($this->once())
-            ->method('isRegistrationAllowed')
-            ->will($this->returnValue(true));
-
-        $this->redirectMock->expects($this->never())
-            ->method('redirect');
-
-        $layoutMock = $this->getMock(
-            'Magento\Framework\View\Layout',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $layoutMock->expects($this->once())
-            ->method('initMessages')
-            ->will($this->returnSelf());
-
-        $this->viewMock->expects($this->once())
-            ->method('loadLayout')
-            ->will($this->returnSelf());
-        $this->viewMock->expects($this->once())
-            ->method('getLayout')
-            ->will($this->returnValue($layoutMock));
-        $this->viewMock->expects($this->once())
-            ->method('renderLayout')
-            ->will($this->returnSelf());
-
-        $this->object->createAction();
-    }
-
-    /**
-     * @return void
-     */
-    public function testCreatePostActionRegistrationDisabled()
-    {
-        $this->customerSession->expects($this->once())
-            ->method('isLoggedIn')
-            ->will($this->returnValue(false));
-
-        $this->customerHelperMock->expects($this->once())
-            ->method('isRegistrationAllowed')
-            ->will($this->returnValue(false));
-
-        $this->redirectMock->expects($this->once())
-            ->method('redirect')
-            ->with($this->response, '*/*/', array())
-            ->will($this->returnValue(false));
-
-        $this->customerAccountServiceMock->expects($this->never())
-            ->method('createCustomer');
-
-        $this->object->createPostAction();
+        $this->object->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/NewsletterTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/NewsletterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab555037798c72d7e072627db1d427568551820d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/NewsletterTest.php
@@ -0,0 +1,229 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Customer\Controller\Adminhtml\Index;
+
+/**
+ * Unit test for \Magento\Customer\Controller\Adminhtml\Index controller
+ */
+class NewsletterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Request mock instance
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\RequestInterface
+     */
+    protected $_request;
+
+    /**
+     * Response mock instance
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\ResponseInterface
+     */
+    protected $_response;
+
+    /**
+     * Instance of mocked tested object
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Controller\Adminhtml\Index
+     */
+    protected $_testedObject;
+
+    /**
+     * ObjectManager mock instance
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\App\ObjectManager
+     */
+    protected $_objectManager;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Customer\Service\V1\CustomerAccountServiceInterface
+     */
+    protected $_acctServiceMock;
+
+    /**
+     * Session mock instance
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Backend\Model\Session
+     */
+    protected $_session;
+
+    /**
+     * Backend helper mock instance
+     *
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Backend\Helper\Data
+     */
+    protected $_helper;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Message\ManagerInterface
+     */
+    protected $messageManager;
+
+    /**
+     * Prepare required values
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function setUp()
+    {
+        $this->_request = $this->getMockBuilder('Magento\Framework\App\Request\Http')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_response = $this->getMockBuilder(
+            'Magento\Framework\App\Response\Http'
+        )->disableOriginalConstructor()->setMethods(
+                array('setRedirect', 'getHeader')
+            )->getMock();
+
+        $this->_response->expects(
+            $this->any()
+        )->method(
+                'getHeader'
+            )->with(
+                $this->equalTo('X-Frame-Options')
+            )->will(
+                $this->returnValue(true)
+            );
+
+        $this->_objectManager = $this->getMockBuilder(
+            'Magento\Framework\App\ObjectManager'
+        )->disableOriginalConstructor()->setMethods(
+                array('get', 'create')
+            )->getMock();
+        $frontControllerMock = $this->getMockBuilder(
+            'Magento\Framework\App\FrontController'
+        )->disableOriginalConstructor()->getMock();
+
+        $actionFlagMock = $this->getMockBuilder('Magento\Framework\App\ActionFlag')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->_session = $this->getMockBuilder(
+            'Magento\Backend\Model\Session'
+        )->disableOriginalConstructor()->setMethods(
+                array('setIsUrlNotice', '__wakeup')
+            )->getMock();
+        $this->_session->expects($this->any())->method('setIsUrlNotice');
+
+        $this->_helper = $this->getMockBuilder(
+            'Magento\Backend\Helper\Data'
+        )->disableOriginalConstructor()->setMethods(
+                array('getUrl')
+            )->getMock();
+
+        $this->messageManager = $this->getMockBuilder(
+            'Magento\Framework\Message\Manager'
+        )->disableOriginalConstructor()->setMethods(
+                array('addSuccess', 'addMessage', 'addException')
+            )->getMock();
+
+        $contextArgs = array(
+            'getHelper',
+            'getSession',
+            'getAuthorization',
+            'getTranslator',
+            'getObjectManager',
+            'getFrontController',
+            'getActionFlag',
+            'getMessageManager',
+            'getLayoutFactory',
+            'getEventManager',
+            'getRequest',
+            'getResponse',
+            'getTitle',
+            'getView'
+        );
+        $contextMock = $this->getMockBuilder(
+            '\Magento\Backend\App\Action\Context'
+        )->disableOriginalConstructor()->setMethods(
+                $contextArgs
+            )->getMock();
+        $contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->_request));
+        $contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->_response));
+        $contextMock->expects(
+            $this->any()
+        )->method(
+                'getObjectManager'
+            )->will(
+                $this->returnValue($this->_objectManager)
+            );
+        $contextMock->expects(
+            $this->any()
+        )->method(
+                'getFrontController'
+            )->will(
+                $this->returnValue($frontControllerMock)
+            );
+        $contextMock->expects($this->any())->method('getActionFlag')->will($this->returnValue($actionFlagMock));
+
+        $contextMock->expects($this->any())->method('getHelper')->will($this->returnValue($this->_helper));
+        $contextMock->expects($this->any())->method('getSession')->will($this->returnValue($this->_session));
+        $contextMock->expects(
+            $this->any()
+        )->method(
+                'getMessageManager'
+            )->will(
+                $this->returnValue($this->messageManager)
+            );
+        $titleMock =  $this->getMockBuilder('\Magento\Framework\App\Action\Title')->getMock();
+        $contextMock->expects($this->any())->method('getTitle')->will($this->returnValue($titleMock));
+        $viewMock =  $this->getMockBuilder('\Magento\Framework\App\ViewInterface')->getMock();
+        $viewMock->expects($this->any())->method('loadLayout')->will($this->returnSelf());
+        $contextMock->expects($this->any())->method('getView')->will($this->returnValue($viewMock));
+
+        $this->_acctServiceMock = $this->getMockBuilder(
+            'Magento\Customer\Service\V1\CustomerAccountServiceInterface'
+        )->getMock();
+
+        $args = array('context' => $contextMock, 'accountService' => $this->_acctServiceMock);
+
+
+
+        $helperObjectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+        $this->_testedObject = $helperObjectManager->getObject(
+            'Magento\Customer\Controller\Adminhtml\Index\Newsletter',
+            $args
+        );
+    }
+
+    public function testNewsletterAction()
+    {
+        $subscriberMock = $this->getMock(
+            '\Magento\Newsletter\Model\Subscriber',
+            array(),
+            array(),
+            '',
+            false
+        );
+        $subscriberMock->expects($this->once())->method('loadByCustomerId');
+        $this->_objectManager
+            ->expects($this->at(1))
+            ->method('create')
+            ->with('Magento\Newsletter\Model\Subscriber')
+            ->will($this->returnValue($subscriberMock));
+        $this->_testedObject->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php
similarity index 92%
rename from dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
rename to dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php
index cc50faf1497384489209b2497047129fc2392a3e..d2cbbce45a4ada3a96b5b6b37b2e22c42778dfb2 100644
--- a/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/IndexTest.php
+++ b/dev/tests/unit/testsuite/Magento/Customer/Controller/Adminhtml/Index/ResetPasswordTest.php
@@ -21,7 +21,7 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Customer\Controller\Adminhtml;
+namespace Magento\Customer\Controller\Adminhtml\Index;
 
 use Magento\Customer\Service\V1\CustomerAccountServiceInterface;
 use Magento\Framework\Exception\NoSuchEntityException;
@@ -30,7 +30,7 @@ use Magento\Customer\Service\V1\Data\Customer;
 /**
  * Unit test for \Magento\Customer\Controller\Adminhtml\Index controller
  */
-class IndexTest extends \PHPUnit_Framework_TestCase
+class ResetPasswordTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * Request mock instance
@@ -207,7 +207,10 @@ class IndexTest extends \PHPUnit_Framework_TestCase
 
 
         $helperObjectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->_testedObject = $helperObjectManager->getObject('Magento\Customer\Controller\Adminhtml\Index', $args);
+        $this->_testedObject = $helperObjectManager->getObject(
+            'Magento\Customer\Controller\Adminhtml\Index\ResetPassword',
+            $args
+        );
     }
 
     public function testResetPasswordActionNoCustomer()
@@ -236,7 +239,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_response->expects($this->once())->method('setRedirect')->with($this->equalTo($redirectLink));
-        $this->_testedObject->resetPasswordAction();
+        $this->_testedObject->execute();
     }
 
     public function testResetPasswordActionInvalidCustomerId()
@@ -281,7 +284,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_response->expects($this->once())->method('setRedirect')->with($this->equalTo($redirectLink));
-        $this->_testedObject->resetPasswordAction();
+        $this->_testedObject->execute();
     }
 
     public function testResetPasswordActionCoreException()
@@ -317,7 +320,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
         // Verify error message is set
         $this->messageManager->expects($this->once())->method('addMessage')->with($this->equalTo($error));
 
-        $this->_testedObject->resetPasswordAction();
+        $this->_testedObject->execute();
     }
 
     public function testResetPasswordActionCoreExceptionWarn()
@@ -360,7 +363,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
             $this->equalTo(new \Magento\Framework\Message\Error($warningText))
         );
 
-        $this->_testedObject->resetPasswordAction();
+        $this->_testedObject->execute();
     }
 
     public function testResetPasswordActionException()
@@ -401,7 +404,7 @@ class IndexTest extends \PHPUnit_Framework_TestCase
             $this->equalTo('An error occurred while resetting customer password.')
         );
 
-        $this->_testedObject->resetPasswordAction();
+        $this->_testedObject->execute();
     }
 
     public function testResetPasswordActionSendEmail()
@@ -477,24 +480,6 @@ class IndexTest extends \PHPUnit_Framework_TestCase
 
         $this->_response->expects($this->once())->method('setRedirect')->with($this->equalTo($redirectLink));
 
-        $this->_testedObject->resetPasswordAction();
-    }
-
-    public function testNewsletterAction()
-    {
-        $subscriberMock = $this->getMock(
-            '\Magento\Newsletter\Model\Subscriber',
-            array(),
-            array(),
-            '',
-            false
-        );
-        $subscriberMock->expects($this->once())->method('loadByCustomerId');
-        $this->_objectManager
-            ->expects($this->at(1))
-            ->method('create')
-            ->with('Magento\Newsletter\Model\Subscriber')
-            ->will($this->returnValue($subscriberMock));
-        $this->_testedObject->newsletterAction();
+        $this->_testedObject->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Block/Adminhtml/Editor/ContainerTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Block/Adminhtml/Editor/ContainerTest.php
index 1c00d9378661154b86b187fa3c3f35741eeaf6f2..134ef96bfa816a399abbf203fc6a7cd1f491b02f 100644
--- a/dev/tests/unit/testsuite/Magento/DesignEditor/Block/Adminhtml/Editor/ContainerTest.php
+++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Block/Adminhtml/Editor/ContainerTest.php
@@ -76,26 +76,22 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
     {
         $buttonTitle = 'Back';
         $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', array(), array(), '', false);
+        $buttonList = $this->getMock('Magento\Backend\Block\Widget\Button\ButtonList', array(), array(), '', false);
         $arguments = $this->_getBlockArguments();
         $arguments['eventManager'] = $eventManager;
+        $arguments['buttonList'] = $buttonList;
+
 
         /** @var $block \Magento\DesignEditor\Block\Adminhtml\Editor\Container */
         $block = $this->_helper->getObject('Magento\DesignEditor\Block\Adminhtml\Editor\Container', $arguments);
 
         $layout = $this->getMock('Magento\Framework\View\Layout', array(), array(), '', false);
-        $block->setLayout($layout);
-
         $expectedButtonData = array(
-            'back_button' => array(
                 'label' => $buttonTitle,
                 'onclick' => 'setLocation(\'\')',
-                'class' => 'back',
-                'id' => 'back_button',
-                'region' => 'toolbar',
-                'sort_order' => 10
-            )
+                'class' => 'back'
         );
-
-        $this->assertAttributeContains($expectedButtonData, '_buttons', $block);
+        $buttonList->expects($this->once())->method('add')->with('back_button', $expectedButtonData, 0, 0, 'toolbar');
+        $block->setLayout($layout);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2fb597f357a1ec4a9393ccc45df65eb38f48e4d3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/FirstEntranceTest.php
@@ -0,0 +1,236 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+/**
+ * Test backend controller for the design editor
+ */
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
+
+class FirstEntranceTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
+     */
+    protected $_model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_objectManagerMock;
+
+    protected function setUp()
+    {
+        $this->_objectManagerMock = $this->getMock('Magento\Framework\ObjectManager');
+
+        $request = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false);
+        $request->expects($this->any())->method('setActionName')->will($this->returnSelf());
+
+        $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        /** @var $layoutMock \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject */
+        $layoutMock = $this->getMock(
+            'Magento\Framework\View\Layout',
+            array(
+                'getBlock',
+                'getUpdate',
+                'addHandle',
+                'load',
+                'generateXml',
+                'getNode',
+                'generateElements',
+                'getMessagesBlock'
+            ),
+            array(),
+            '',
+            false
+        );
+        /** @var $layoutMock \Magento\Framework\View\LayoutInterface */
+        $layoutMock->expects($this->any())->method('generateXml')->will($this->returnSelf());
+        $layoutMock->expects(
+            $this->any()
+        )->method(
+                'getNode'
+            )->will(
+                $this->returnValue(new \Magento\Framework\Simplexml\Element('<root />'))
+            );
+        $blockMessage = $this->getMock(
+            'Magento\Framework\View\Element\Messages',
+            array('addMessages', 'setEscapeMessageFlag', 'addStorageType'),
+            array(),
+            '',
+            false
+        );
+        $layoutMock->expects($this->any())->method('getMessagesBlock')->will($this->returnValue($blockMessage));
+
+        $blockMock = $this->getMock(
+            'Magento\Framework\View\Element\Template',
+            array('setActive', 'getMenuModel', 'getParentItems'),
+            array(),
+            '',
+            false
+        );
+        $blockMock->expects($this->any())->method('getMenuModel')->will($this->returnSelf());
+        $blockMock->expects($this->any())->method('getParentItems')->will($this->returnValue(array()));
+
+        $layoutMock->expects($this->any())->method('getBlock')->will($this->returnValue($blockMock));
+        $layoutMock->expects($this->any())->method('getUpdate')->will($this->returnSelf());
+
+        $constructArguments = $objectManagerHelper->getConstructArguments(
+            'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor',
+            array(
+                'request' => $request,
+                'objectManager' => $this->_objectManagerMock,
+                'layout' => $layoutMock,
+                'invokeArgs' => array(
+                    'helper' => $this->getMock('Magento\Backend\Helper\Data', array(), array(), '', false),
+                    'session' => $this->getMock('Magento\Backend\Model\Session', array(), array(), '', false)
+                )
+            )
+        );
+
+        $this->_model = $objectManagerHelper->getObject(
+            'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\FirstEntrance',
+            $constructArguments
+        );
+    }
+
+    /**
+     * Return mocked theme collection factory model
+     *
+     * @param int $countCustomization
+     * @return \Magento\Core\Model\Resource\Theme\CollectionFactory
+     */
+    protected function _getThemeCollectionFactory($countCustomization)
+    {
+        $themeCollectionMock = $this->getMockBuilder(
+            'Magento\Core\Model\Resource\Theme\Collection'
+        )->disableOriginalConstructor()->setMethods(
+                array('addTypeFilter', 'getSize')
+            )->getMock();
+
+        $themeCollectionMock->expects(
+            $this->once()
+        )->method(
+                'addTypeFilter'
+            )->with(
+                \Magento\Framework\View\Design\ThemeInterface::TYPE_VIRTUAL
+            )->will(
+                $this->returnValue($themeCollectionMock)
+            );
+
+        $themeCollectionMock->expects($this->once())->method('getSize')->will($this->returnValue($countCustomization));
+
+        /** @var \Magento\Core\Model\Resource\Theme\CollectionFactory $collectionFactory */
+        $collectionFactory = $this->getMock(
+            'Magento\Core\Model\Resource\Theme\CollectionFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $collectionFactory->expects($this->once())->method('create')->will($this->returnValue($themeCollectionMock));
+
+        return $collectionFactory;
+    }
+
+    /**
+     * @covers \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor::firstEntranceAction
+     * @dataProvider firstEntranceActionDataProvider
+     */
+    public function testFirstEntranceAction($countCustomization)
+    {
+        $this->_objectManagerMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->will(
+                $this->returnValueMap($this->_getObjectManagerMap($countCustomization))
+            );
+        $this->assertNull($this->_model->execute());
+    }
+
+    /**
+     * @return array
+     */
+    public function firstEntranceActionDataProvider()
+    {
+        return array(array(3), array(0));
+    }
+
+    /**
+     * @param int $countCustomization
+     * @return array
+     */
+    protected function _getObjectManagerMap($countCustomization)
+    {
+        $translate = $this->getMock('Magento\Framework\TranslateInterface', array(), array(), '', false);
+        $translate->expects($this->any())->method('translate')->will($this->returnSelf());
+
+        $storeManager = $this->getMock(
+            'Magento\Store\Model\StoreManager',
+            array('getStore', 'getBaseUrl'),
+            array(),
+            '',
+            false
+        );
+        $storeManager->expects($this->any())->method('getStore')->will($this->returnSelf());
+
+        $eventManager = $this->getMock('Magento\Framework\Event\ManagerInterface', array(), array(), '', false);
+        $configMock = $this->getMock('Magento\Framework\App\Config\ScopeConfigInterface');
+        $authMock = $this->getMock('Magento\Framework\AuthorizationInterface');
+        $authMock->expects($this->any())->method('filterAclNodes')->will($this->returnSelf());
+        $backendSession = $this->getMock(
+            'Magento\Backend\Model\Session',
+            array('getMessages', 'getEscapeMessages'),
+            array(),
+            '',
+            false
+        );
+        $backendSession->expects(
+            $this->any()
+        )->method(
+                'getMessages'
+            )->will(
+                $this->returnValue($this->getMock('Magento\Framework\Message\Collection', array(), array(), '', false))
+            );
+
+        $inlineMock = $this->getMock('Magento\Framework\Translate\Inline', array(), array(), '', false);
+        $aclFilterMock = $this->getMock('Magento\Backend\Model\Layout\Filter\Acl', array(), array(), '', false);
+
+        return array(
+            array(
+                'Magento\Core\Model\Resource\Theme\CollectionFactory',
+                $this->_getThemeCollectionFactory($countCustomization)
+            ),
+            array('Magento\Framework\TranslateInterface', $translate),
+            array('Magento\Framework\App\Config\ScopeConfigInterface', $configMock),
+            array('Magento\Framework\Event\ManagerInterface', $eventManager),
+            array('Magento\Store\Model\StoreManager', $storeManager),
+            array('Magento\Framework\AuthorizationInterface', $authMock),
+            array('Magento\Backend\Model\Session', $backendSession),
+            array('Magento\Framework\Translate\Inline', $inlineMock),
+            array('Magento\Backend\Model\Layout\Filter\Acl', $aclFilterMock)
+        );
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/EditorTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php
similarity index 90%
rename from dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/EditorTest.php
rename to dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php
index cd87dab5b012c9c1d22848983334a22ad5b454f2..cba4f9fe60233a8f38f6776eb7c5dbe5b8d05184 100644
--- a/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/EditorTest.php
+++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Controller/Adminhtml/System/Design/Editor/IndexTest.php
@@ -25,9 +25,9 @@
 /**
  * Test backend controller for the design editor
  */
-namespace Magento\DesignEditor\Controller\Adminhtml\System\Design;
+namespace Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor;
 
-class EditorTest extends \PHPUnit_Framework_TestCase
+class IndexTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor
@@ -48,7 +48,7 @@ class EditorTest extends \PHPUnit_Framework_TestCase
 
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
 
-        /** @var $layoutMock \Magento\Framework\View\Layout|PHPUnit_Framework_MockObject_MockObject */
+        /** @var $layoutMock \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject */
         $layoutMock = $this->getMock(
             'Magento\Framework\View\Layout',
             array(
@@ -110,7 +110,7 @@ class EditorTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_model = $objectManagerHelper->getObject(
-            'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor',
+            'Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor\Index',
             $constructArguments
         );
     }
@@ -167,7 +167,7 @@ class EditorTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValueMap($this->_getObjectManagerMap($countCustomization, 'index'))
         );
-        $this->assertNull($this->_model->indexAction());
+        $this->assertNull($this->_model->execute());
     }
 
     /**
@@ -178,30 +178,6 @@ class EditorTest extends \PHPUnit_Framework_TestCase
         return array(array(4), array(0));
     }
 
-    /**
-     * @covers \Magento\DesignEditor\Controller\Adminhtml\System\Design\Editor::firstEntranceAction
-     * @dataProvider firstEntranceActionDataProvider
-     */
-    public function testFirstEntranceAction($countCustomization)
-    {
-        $this->_objectManagerMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->will(
-            $this->returnValueMap($this->_getObjectManagerMap($countCustomization))
-        );
-        $this->assertNull($this->_model->firstEntranceAction());
-    }
-
-    /**
-     * @return array
-     */
-    public function firstEntranceActionDataProvider()
-    {
-        return array(array(3), array(0));
-    }
-
     /**
      * @param int $countCustomization
      * @return array
diff --git a/dev/tests/unit/testsuite/Magento/DesignEditor/Model/Url/NavigationModeTest.php b/dev/tests/unit/testsuite/Magento/DesignEditor/Model/Url/NavigationModeTest.php
index af2df7158c398082bb455aeeaa9eed1e206cc31e..01f03c27dc2413310147292be2cd1428b7677b7d 100644
--- a/dev/tests/unit/testsuite/Magento/DesignEditor/Model/Url/NavigationModeTest.php
+++ b/dev/tests/unit/testsuite/Magento/DesignEditor/Model/Url/NavigationModeTest.php
@@ -54,6 +54,11 @@ class NavigationModeTest extends \PHPUnit_Framework_TestCase
      */
     protected $_routeParamsMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $_scopeResolverMock;
+
     /**
      * @var array
      */
@@ -90,12 +95,21 @@ class NavigationModeTest extends \PHPUnit_Framework_TestCase
             )
         );
 
+        $this->_scopeResolverMock =  $this->getMock(
+            'Magento\Framework\Url\ScopeResolverInterface',
+            array(),
+            array(),
+            '',
+            false
+        );
+
         $this->_model = $objectManagerHelper->getObject(
             'Magento\DesignEditor\Model\Url\NavigationMode',
             array(
                 'helper' => $this->_designHelperMock,
                 'data' => $this->_testData,
-                'routeParamsResolver' => $this->_routeParamsMock
+                'routeParamsResolver' => $this->_routeParamsMock,
+                'scopeResolver' => $this->_scopeResolverMock
             )
         );
     }
@@ -146,6 +160,10 @@ class NavigationModeTest extends \PHPUnit_Framework_TestCase
             '/' .
             self::ROUTE_PATH;
 
+        $this->_scopeResolverMock->expects(
+            $this->any()
+        )->method('getScope')->will($this->returnValue($store));
+
         $this->assertEquals($expectedUrl, $this->_model->getRouteUrl($sourceUrl));
         $this->assertEquals($expectedUrl, $this->_model->getRouteUrl($expectedUrl));
     }
diff --git a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
index 97020571853d64b16977ca47f649c9b12cf7a0fb..5c987660e37ffb5e93889ec900e7a2e9225e02d9 100644
--- a/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Downloadable/Service/V1/DownloadableLink/ReadServiceTest.php
@@ -299,4 +299,4 @@ class ReadServiceTest extends \PHPUnit_Framework_TestCase
             ],
         ];
     }
-}
\ No newline at end of file
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Helper/DataTest.php b/dev/tests/unit/testsuite/Magento/Eav/Helper/DataTest.php
index 42576df2f9cf248a85d0d4e1dbe03013df6cf4da..d95859eb7a8321fa8b9901bff329fa4a84e9d81a 100644
--- a/dev/tests/unit/testsuite/Magento/Eav/Helper/DataTest.php
+++ b/dev/tests/unit/testsuite/Magento/Eav/Helper/DataTest.php
@@ -36,16 +36,21 @@ class DataTest extends \PHPUnit_Framework_TestCase
      */
     protected $_eavConfig;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $attributeConfig;
+
     /**
      * Initialize helper
      */
     protected function setUp()
     {
         $context = $this->getMock('\Magento\Framework\App\Helper\Context', [], [], '', false);
-        $attributeConfig = $this->getMock('\Magento\Eav\Model\Entity\Attribute\Config', [], [], '', false);
+        $this->attributeConfig = $this->getMock('\Magento\Eav\Model\Entity\Attribute\Config', [], [], '', false);
         $scopeConfig = $this->getMock('\Magento\Framework\App\Config\ScopeConfigInterface', [], [], '', false);
         $eavConfig = $this->getMock('\Magento\Eav\Model\Config', [], [], '', false);
-        $this->_helper = new Data($context, $attributeConfig, $scopeConfig, $eavConfig);
+        $this->_helper = new Data($context, $this->attributeConfig, $scopeConfig, $eavConfig);
         $this->_eavConfig = $eavConfig;
     }
 
@@ -78,4 +83,62 @@ class DataTest extends \PHPUnit_Framework_TestCase
             );
         }
     }
+
+    /**
+     * @covers \Magento\Eav\Helper\Data::getFrontendClasses
+     * @covers \Magento\Eav\Helper\Data::_getDefaultFrontendClasses
+     */
+    public function testGetFrontendClasses()
+    {
+        $result = $this->_helper->getFrontendClasses('someNonExistedClass');
+        $this->assertTrue(count($result) > 1);
+        $this->assertContains(['value' => '', 'label' => 'None'], $result);
+        $this->assertContains(['value' => 'validate-number', 'label' => 'Decimal Number'], $result);
+    }
+
+    /**
+     * @covers \Magento\Eav\Helper\Data::getAttributeLockedFields
+     */
+    public function testGetAttributeLockedFieldsNoEntityCode()
+    {
+        $this->attributeConfig->expects($this->never())->method('getEntityAttributesLockedFields');
+        $this->assertEquals([], $this->_helper->getAttributeLockedFields(''));
+    }
+
+    /**
+     * @covers \Magento\Eav\Helper\Data::getAttributeLockedFields
+     */
+    public function testGetAttributeLockedFieldsNonCachedLockedFiled()
+    {
+        $lockedFields = ['lockedField1', 'lockedField2'];
+
+        $this->attributeConfig->expects($this->once())->method('getEntityAttributesLockedFields')
+            ->with('entityTypeCode')->will($this->returnValue($lockedFields));
+        $this->assertEquals($lockedFields, $this->_helper->getAttributeLockedFields('entityTypeCode'));
+    }
+
+    /**
+     * @covers \Magento\Eav\Helper\Data::getAttributeLockedFields
+     */
+    public function testGetAttributeLockedFieldsCachedLockedFiled()
+    {
+        $lockedFields = ['lockedField1', 'lockedField2'];
+
+        $this->attributeConfig->expects($this->once())->method('getEntityAttributesLockedFields')
+            ->with('entityTypeCode')->will($this->returnValue($lockedFields));
+
+        $this->_helper->getAttributeLockedFields('entityTypeCode');
+        $this->assertEquals($lockedFields, $this->_helper->getAttributeLockedFields('entityTypeCode'));
+    }
+
+    /**
+     * @covers \Magento\Eav\Helper\Data::getAttributeLockedFields
+     */
+    public function testGetAttributeLockedFieldsNoLockedFields()
+    {
+        $this->attributeConfig->expects($this->once())->method('getEntityAttributesLockedFields')
+            ->with('entityTypeCode')->will($this->returnValue([]));
+
+        $this->assertEquals([], $this->_helper->getAttributeLockedFields('entityTypeCode'));
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ec733ea2949b612c4bef3f222855ba50fcbb995
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/AbstractDataTest.php
@@ -0,0 +1,183 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class AbstractDataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\AbstractData
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+        $stringMock = $this->getMock('\Magento\Framework\Stdlib\String', [], [], '', false);
+
+        /* testing abstract model through its child */
+        $this->model = new Text($timezoneMock, $loggerMock, $localeResolverMock, $stringMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::getEntity
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::setEntity
+     */
+    public function testGetEntity()
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $this->model->setEntity($entityMock);
+        $this->assertEquals($entityMock, $this->model->getEntity());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     * @expectedExceptionMessage Entity object is undefined
+     *
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::getEntity
+     */
+    public function testGetEntityWhenEntityNotSet()
+    {
+        $this->model->getEntity();
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::getExtractedData
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::setExtractedData
+     *
+     * @param string $index
+     * @param mixed $expectedResult
+     *
+     * @dataProvider extractedDataDataProvider
+     */
+    public function testGetExtractedData($index, $expectedResult)
+    {
+        $extractedData = ['index' => 'value', 'otherIndex' => 'otherValue'];
+        $this->model->setExtractedData($extractedData);
+        $this->assertEquals($expectedResult, $this->model->getExtractedData($index));
+    }
+
+    /**
+     * @return array
+     */
+    public function extractedDataDataProvider()
+    {
+        return [
+            [
+                'index' => 'index',
+                'expectedResult' => 'value'
+            ],
+            [
+                'index' => null,
+                'expectedResult' => ['index' => 'value', 'otherIndex' => 'otherValue']
+            ],
+            [
+                'index' => 'customIndex',
+                'expectedResult' => null
+            ]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\AbstractData::_getRequestValue
+     *
+     * @param string $requestScope
+     * @param string $value
+     * @param string $expectedResult
+     * @param array $params
+     * @param bool $requestScopeOnly
+     * @dataProvider getRequestValueDataProvider
+     */
+    public function testGetRequestValue($requestScope, $value, $params, $requestScopeOnly, $expectedResult)
+    {
+        $requestMock = $this->getMock(
+            '\Magento\Framework\App\Request\Http', ['getParams', 'getParam'], [], '', false
+        );
+        $requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap([
+            ['attributeCode', false, $value],
+            [$requestScope, $value]
+        ]));
+        $requestMock->expects($this->any())->method('getParams')->will($this->returnValue($params));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('attributeCode'));
+
+        $this->model->setAttribute($attributeMock);
+        $this->model->setRequestScope($requestScope);
+        $this->model->setRequestScopeOnly($requestScopeOnly);
+        $this->assertEquals($expectedResult, $this->model->extractValue($requestMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function getRequestValueDataProvider()
+    {
+        return [
+            [
+                'requestScope' => false,
+                'value' => 'value',
+                'params'=> [],
+                'requestScopeOnly' => true,
+                'expectedResult' => 'value'
+            ],
+            [
+                'requestScope' => 'scope/scope',
+                'value' => 'value',
+                'params'=> ['scope' => ['scope' => ['attributeCode' => 'data']]],
+                'requestScopeOnly' => true,
+                'expectedResult' => 'data'
+            ],
+            [
+                'requestScope' => 'scope/scope',
+                'value' => 'value',
+                'params'=> ['scope' => ['scope' => []]],
+                'requestScopeOnly' => true,
+                'expectedResult' => false
+            ],
+            [
+                'requestScope' => 'scope/scope',
+                'value' => 'value',
+                'params'=> ['scope'],
+                'requestScopeOnly' => true,
+                'expectedResult' => false
+            ],
+            [
+                'requestScope' => 'scope',
+                'value' => 'value',
+                'params'=> ['otherScope' => 1],
+                'requestScopeOnly' => true,
+                'expectedResult' => false
+            ],
+            [
+                'requestScope' => 'scope',
+                'value' => 'value',
+                'params'=> ['otherScope' => 1],
+                'requestScopeOnly' => false,
+                'expectedResult' => 'value'
+            ]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..89ae69f7c56d3f704e61221fe73c85ac0fb26260
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/BooleanTest.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class BooleanTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\Boolean
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+
+        $this->model = new Boolean($timezoneMock, $loggerMock, $localeResolverMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Boolean::_getOptionText
+     *
+     * @param string $format
+     * @param mixed $value
+     * @param mixed $expectedResult
+     * @dataProvider getOptionTextDataProvider
+     */
+    public function testOutputValue($format, $value, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue($value));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function getOptionTextDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => '0',
+                'expectedResult' => 'No'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => '1',
+                'expectedResult' => 'Yes'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => '2',
+                'expectedResult' => ''
+            ],
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba73b4654eeaafcde186116c6587968ad1ad83a3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/DateTest.php
@@ -0,0 +1,208 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class DateTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\Date
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $timezoneMock;
+
+    protected function setUp()
+    {
+        $this->timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+
+        $this->model = new Date($this->timezoneMock, $loggerMock, $localeResolverMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Date::outputValue
+     *
+     * @param string $format
+     * @param mixed $value
+     * @param mixed $expectedResult
+     * @param int $callTimes
+     * @dataProvider outputValueDataProvider
+     */
+    public function testOutputValue($format, $value, $callTimes, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue($value));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', ['getInputFilter', '__wakeup'], [], '', false);
+        $attributeMock->expects($this->exactly($callTimes))->method('getInputFilter')->will($this->returnValue(false));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function outputValueDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => 'value',
+                'callTimes' => 1,
+                'expectedResult' => 'value'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => false,
+                'callTimes' => 0,
+                'expectedResult' => false
+            ],
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Date::validateValue
+     *
+     * @param mixed $value
+     * @param array $rules
+     * @param mixed $originalValue
+     * @param bool $isRequired
+     * @param array $expectedResult
+     * @dataProvider validateValueDataProvider
+     */
+    public function testValidateValue($value, $rules, $originalValue, $isRequired, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->any())->method('getDataUsingMethod')->will($this->returnValue($originalValue));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
+        $attributeMock->expects($this->any())->method('getIsRequired')->will($this->returnValue($isRequired));
+        $attributeMock->expects($this->any())->method('getValidateRules')->will($this->returnValue($rules));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->validateValue($value));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateValueDataProvider()
+    {
+        return [
+            [
+                'value' => false,
+                'rules' => [],
+                'originalValue' => false,
+                'isRequired' => true,
+                'expectedResult' => ['"Label" is a required value.'],
+            ],
+            [
+                'value' => 'value',
+                'rules' => [],
+                'originalValue' => 'value',
+                'isRequired' => false,
+                'expectedResult' => true,
+            ],
+            [
+                'value' => null,
+                'rules' => [],
+                'originalValue' => '',
+                'isRequired' => false,
+                'expectedResult' => true,
+            ],
+            [
+                'value' => '2000-01-01',
+                'rules' => ['date_range_min' => strtotime('2001-01-01'),'date_range_max' => strtotime('2002-01-01')],
+                'originalValue' => '',
+                'isRequired' => false,
+                'expectedResult' => ['Please enter a valid date between 01/01/2001 and 01/01/2002 at Label.'],
+            ],
+            [
+                'value' => '2000-01-01',
+                'rules' => ['date_range_min' => strtotime('2001-01-01')],
+                'originalValue' => '',
+                'isRequired' => false,
+                'expectedResult' => ['Please enter a valid date equal to or greater than 01/01/2001 at Label.'],
+            ],
+            [
+                'value' => '2010-01-01',
+                'rules' => ['date_range_max' => strtotime('2001-01-01')],
+                'originalValue' => '',
+                'isRequired' => false,
+                'expectedResult' => ['Please enter a valid date less than or equal to 01/01/2001 at Label.'],
+            ],
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Date::compactValue
+     *
+     * @param string $value
+     * @param string $expectedResult
+     * @dataProvider compactValueDataProvider
+     */
+    public function testCompactValue($value, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('setDataUsingMethod')->with('attrCode', $expectedResult);
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('attrCode'));
+
+        $this->model->setAttribute($attributeMock);
+        $this->model->setEntity($entityMock);
+        $this->model->compactValue($value);
+    }
+
+    /**
+     * @return array
+     */
+    public function compactValueDataProvider()
+    {
+        return [
+            ['value' => 'value', 'expectedResult' => 'value'],
+            ['value' => '',  'expectedResult' => null]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Date::compactValue
+     */
+    public function testCompactValueWithFalseValue()
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->never())->method('setDataUsingMethod');
+
+        $this->model->setEntity($entityMock);
+        $this->model->compactValue(false);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..eea20cd373b850a46ecf5125b7b5b4186252342b
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/FileTest.php
@@ -0,0 +1,291 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class FileTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\File
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreDataMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $fileValidatorMock;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+        $this->coreDataMock = $this->getMock('\Magento\Core\Helper\Data', [], [], '', false);
+        $this->fileValidatorMock = $this->getMock(
+            '\Magento\Core\Model\File\Validator\NotProtectedExtension', ['isValid', 'getMessages'], [], '', false
+        );
+        $filesystemMock = $this->getMock('\Magento\Framework\App\Filesystem', [], [], '', false);
+
+        $this->model = new File(
+            $timezoneMock, $loggerMock, $localeResolverMock,
+            $this->coreDataMock, $this->fileValidatorMock, $filesystemMock
+        );
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\File::outputValue
+     *
+     * @param string $format
+     * @param mixed $value
+     * @param mixed $expectedResult
+     * @param int $callTimes
+     * @dataProvider outputValueDataProvider
+     */
+    public function testOutputValue($format, $value, $callTimes, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue($value));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $this->coreDataMock->expects($this->exactly($callTimes))->method('urlEncode')
+            ->will($this->returnValue('url_key'));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function outputValueDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON,
+                'value' => 'value',
+                'callTimes' => 1,
+                'expectedResult' => ['value' => 'value', 'url_key' => 'url_key']
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => 'value',
+                'callTimes' => 0,
+                'expectedResult' => ''
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => false,
+                'callTimes' => 0,
+                'expectedResult' => ''
+            ],
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\File::validateValue
+     * @covers \Magento\Eav\Model\Attribute\Data\File::_validateByRules
+     *
+     * @param mixed $value
+     * @param mixed $originalValue
+     * @param bool $isRequired
+     * @param bool $isAjaxRequest
+     * @param array $rules
+     * @param bool $fileIsValid
+     * @param array $expectedResult
+     * @dataProvider validateValueDataProvider
+     */
+    public function testValidateValue(
+        $value, $originalValue, $isRequired, $isAjaxRequest, $rules, $fileIsValid, $expectedResult
+    ) {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->any())->method('getData')->will($this->returnValue($originalValue));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
+        $attributeMock->expects($this->any())->method('getIsRequired')->will($this->returnValue($isRequired));
+        $attributeMock->expects($this->any())->method('getIsAjaxRequest')->will($this->returnValue($isAjaxRequest));
+        $attributeMock->expects($this->any())->method('getValidateRules')->will($this->returnValue($rules));
+
+        $this->fileValidatorMock->expects($this->any())->method('isValid')->will($this->returnValue($fileIsValid));
+        $this->fileValidatorMock->expects($this->any())->method('getMessages')->will($this->returnValue(['m1', 'm2']));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->model->setIsAjaxRequest($isAjaxRequest);
+        $this->assertEquals($expectedResult, $this->model->validateValue($value));
+    }
+
+    /**
+     * @return array
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function validateValueDataProvider()
+    {
+        return [
+            [
+                'value' => false,
+                'originalValue' => false,
+                'isRequired' => true,
+                'isAjaxRequest' => true,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => '', 'tmp_name' => ''],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => ''],
+                'originalValue' => 'value',
+                'isRequired' => false,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => ''],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => ['"Label" is a required value.']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete', 'tmp_name' => 'tmp_name', 'name' => 'name'
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'tmp_name',
+                    'name' => 'name.txt',
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['file_extensions' => 'txt,png'],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'tmp_name',
+                    'name' => 'name.rpg',
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['file_extensions' => ' txt , png '],
+                'fileIsValid' => true,
+                'expectedResult' => ['"Label" is not a valid file extension.']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'tmp_name',
+                    'name' => 'name.txt',
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['file_extensions' => ''],
+                'fileIsValid' => false,
+                'expectedResult' => ['m1', 'm2']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'NotUploaded',
+                    'name' => '',
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'fileIsValid' => true,
+                'expectedResult' => ['"Label" is not a valid file.']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'tmp_name',
+                    'name' => 'name.txt',
+                    'size' => 20
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_file_size' => 10],
+                'fileIsValid' => true,
+                'expectedResult' => ['"Label" exceeds the allowed file size.']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete',
+                    'tmp_name' => 'tmp_name',
+                    'name' => 'name.txt',
+                    'size' => 5
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_file_size' => 10],
+                'fileIsValid' => true,
+                'expectedResult' => true
+            ],
+        ];
+    }
+};
+
+/**
+ * Mocking of std function to test validation
+ *
+ * @param string $name
+ * @return bool
+ */
+function is_uploaded_file($name)
+{
+    return ($name == 'NotUploaded') ? false : true;
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f605dc45ecaa6fb1f7db61af55b4ab5c222d3d1f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/ImageTest.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class ImageTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\File
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+        $coreDataMock = $this->getMock('\Magento\Core\Helper\Data', [], [], '', false);
+        $fileValidatorMock = $this->getMock(
+            '\Magento\Core\Model\File\Validator\NotProtectedExtension', [], [], '', false
+        );
+        $filesystemMock = $this->getMock('\Magento\Framework\App\Filesystem', [], [], '', false);
+
+        $this->model = new Image(
+            $timezoneMock, $loggerMock, $localeResolverMock, $coreDataMock, $fileValidatorMock, $filesystemMock
+        );
+    }
+
+    /**
+     * Attention: this test depends on mock of "is_uploaded_file" function in ./FileTest.php,
+     * so validates method successfully in batch run of directory tests, separately will fail.
+     * 
+     * @covers \Magento\Eav\Model\Attribute\Data\Image::_validateByRules
+     *
+     * @param mixed $value
+     * @param mixed $originalValue
+     * @param bool $isRequired
+     * @param bool $isAjaxRequest
+     * @param array $rules
+     * @param array $expectedResult
+     * @dataProvider validateValueDataProvider
+     */
+    public function testValidateValue(
+        $value, $originalValue, $isRequired, $isAjaxRequest, $rules, $expectedResult
+    ) {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->any())->method('getData')->will($this->returnValue($originalValue));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
+        $attributeMock->expects($this->any())->method('getIsRequired')->will($this->returnValue($isRequired));
+        $attributeMock->expects($this->any())->method('getIsAjaxRequest')->will($this->returnValue($isAjaxRequest));
+        $attributeMock->expects($this->any())->method('getValidateRules')->will($this->returnValue($rules));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->model->setIsAjaxRequest($isAjaxRequest);
+        $this->assertEquals($expectedResult, $this->model->validateValue($value));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateValueDataProvider()
+    {
+        return [
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => 'NotUploaded'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'expectedResult' => ['"Label" is not a valid file']
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.ico', 'name' => 'image.ico'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'expectedResult' => ['"Label" is not a valid image format']
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.ppp'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => [],
+                'expectedResult' => true
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg',
+                    'name' => 'image.jpg', 'size' => 10
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_file_size' => 2],
+                'expectedResult' => ['"Label" exceeds the allowed file size.']
+            ],
+            [
+                'value' => [
+                    'delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg',
+                    'name' => 'image.jpg', 'size' => 10
+                ],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_file_size' => 20],
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.jpg'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_image_width' => 2],
+                'expectedResult' => ['"Label" width exceeds allowed value of 2 px.']
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.jpg'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_image_width' => 2000],
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.jpg'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_image_heght' => 2],
+                'expectedResult' => ['"Label" height exceeds allowed value of 2 px.']
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.jpg'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_image_heght' => 2000],
+                'expectedResult' => true
+            ],
+            [
+                'value' => ['delete' => 'delete', 'tmp_name' => __DIR__ . '/_files/image.jpg', 'name' => 'image.jpg'],
+                'originalValue' => 'value',
+                'isRequired' => true,
+                'isAjaxRequest' => false,
+                'rules' => ['max_image_heght' => 2, 'max_image_width' => 2],
+                'expectedResult' => [
+                    '"Label" width exceeds allowed value of 2 px.',
+                    '"Label" height exceeds allowed value of 2 px.'
+                ]
+            ],
+        ];
+    }
+};
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8db21719266e209cde93f0444523a593c08fb81d
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultilineTest.php
@@ -0,0 +1,187 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class MultilineTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\Multiline
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stringMock;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+        $this->stringMock = $this->getMock('\Magento\Framework\Stdlib\String', [], [], '', false);
+
+        $this->model = new Multiline($timezoneMock, $loggerMock, $localeResolverMock, $this->stringMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Multiline::extractValue
+     *
+     * @param mixed $param
+     * @param mixed $expectedResult
+     * @dataProvider extractValueDataProvider
+     */
+    public function testExtractValue($param, $expectedResult)
+    {
+        $requestMock = $this->getMock('\Magento\Framework\App\RequestInterface');
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+
+        $requestMock->expects($this->once())->method('getParam')->will($this->returnValue($param));
+        $attributeMock->expects($this->once())->method('getAttributeCode')->will($this->returnValue('attributeCode'));
+
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->extractValue($requestMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function extractValueDataProvider()
+    {
+        return [
+            [
+                'param' => 'param',
+                'expectedResult' => false
+            ],
+            [
+                'param' => ['param'],
+                'expectedResult' => ['param']
+            ],
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Multiline::outputValue
+     *
+     * @param string $format
+     * @param mixed $expectedResult
+     * @dataProvider outputValueDataProvider
+     */
+    public function testOutputValue($format, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue("value1\nvalue2"));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function outputValueDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_ARRAY,
+                'expectedResult' => ['value1', 'value2']
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_HTML,
+                'expectedResult' => 'value1<br />value2'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_ONELINE,
+                'expectedResult' => 'value1 value2'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'expectedResult' => "value1\nvalue2"
+            ]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Multiline::validateValue
+     * @covers \Magento\Eav\Model\Attribute\Data\Text::validateValue
+     *
+     * @param mixed $value
+     * @param array $rules
+     * @param array $expectedResult
+     * @dataProvider validateValueDataProvider
+     */
+    public function testValidateValue($value, $rules, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->any())->method('getDataUsingMethod')->will($this->returnValue("value1\nvalue2"));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getMultilineCount')->will($this->returnValue(2));
+        $attributeMock->expects($this->any())->method('getValidateRules')->will($this->returnValue($rules));
+        $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
+
+        $this->stringMock->expects($this->any())->method('strlen')->will($this->returnValue(5));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->validateValue($value));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateValueDataProvider()
+    {
+        return [
+            [
+                'value' => false,
+                'rules' => [],
+                'expectedResult' => true,
+            ],
+            [
+                'value' => 'value',
+                'rules' => [],
+                'expectedResult' => true,
+            ],
+            [
+                'value' => ['value1',  'value2'],
+                'rules' => [],
+                'expectedResult' => true,
+            ],
+            [
+                'value' => 'value',
+                'rules' => ['max_text_length' => 3],
+                'expectedResult' => ['"Label" length must be equal or less than 3 characters.'],
+            ],
+            [
+                'value' => 'value',
+                'rules' => ['min_text_length' => 10],
+                'expectedResult' => ['"Label" length must be equal or greater than 10 characters.'],
+            ]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..240ec7ab0e6fc9386e180e8c083433bbaf6c71e2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/MultiselectTest.php
@@ -0,0 +1,121 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class MultiselectTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\Multiselect
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+
+        $this->model = new Multiselect($timezoneMock, $loggerMock, $localeResolverMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Multiselect::extractValue
+     *
+     * @param mixed $param
+     * @param mixed $expectedResult
+     * @dataProvider extractValueDataProvider
+     */
+    public function testExtractValue($param, $expectedResult)
+    {
+        $requestMock = $this->getMock('\Magento\Framework\App\RequestInterface');
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+
+        $requestMock->expects($this->once())->method('getParam')->will($this->returnValue($param));
+        $attributeMock->expects($this->once())->method('getAttributeCode')->will($this->returnValue('attributeCode'));
+
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->extractValue($requestMock));
+    }
+
+    /**
+     * @return array
+     */
+    public function extractValueDataProvider()
+    {
+        return [
+            [
+                'param' => 'param',
+                'expectedResult' => ['param']
+            ],
+            [
+                'param' => false,
+                'expectedResult' => false
+            ],
+            [
+                'param' => ['value'],
+                'expectedResult' => ['value']
+            ]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Multiselect::outputValue
+     *
+     * @param string $format
+     * @param mixed $expectedResult
+     * @dataProvider outputValueDataProvider
+     */
+    public function testOutputValue($format, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue('value1,value2,'));
+
+        $sourceMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource', [], [], '', false);
+        $sourceMock->expects($this->any())->method('getOptionText')->will($this->returnArgument(0));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getSource')->will($this->returnValue($sourceMock));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function outputValueDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON,
+                'expectedResult' => 'value1, value2'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_ONELINE,
+                'expectedResult' => 'value1, value2'
+            ]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ad98a0b110461c1c23819b4850b6945f96a9cc2
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/SelectTest.php
@@ -0,0 +1,179 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Attribute\Data;
+
+class SelectTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Eav\Model\Attribute\Data\Select
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $timezoneMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+        $loggerMock = $this->getMock('\Magento\Framework\Logger', [], [], '', false);
+        $localeResolverMock = $this->getMock('\Magento\Framework\Locale\ResolverInterface');
+
+        $this->model = new Select($timezoneMock, $loggerMock, $localeResolverMock);
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Select::outputValue
+     *
+     * @param string $format
+     * @param mixed $value
+     * @param mixed $expectedResult
+     * @dataProvider outputValueDataProvider
+     */
+    public function testOutputValue($format, $value, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('getData')->will($this->returnValue($value));
+
+        $sourceMock = $this->getMock('\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource', [], [], '', false);
+        $sourceMock->expects($this->any())->method('getOptionText')->will($this->returnValue(123));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getSource')->will($this->returnValue($sourceMock));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->outputValue($format));
+    }
+
+    /**
+     * @return array
+     */
+    public function outputValueDataProvider()
+    {
+        return [
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_JSON,
+                'value' => 'value',
+                'expectedResult' => 'value'
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => '',
+                'expectedResult' => ''
+            ],
+            [
+                'format' => \Magento\Eav\Model\AttributeDataFactory::OUTPUT_FORMAT_TEXT,
+                'value' => 'value',
+                'expectedResult' => '123'
+            ],
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Select::validateValue
+     *
+     * @param mixed $value
+     * @param mixed $originalValue
+     * @param bool $isRequired
+     * @param array $expectedResult
+     * @dataProvider validateValueDataProvider
+     */
+    public function testValidateValue($value, $originalValue, $isRequired, $expectedResult)
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->any())->method('getData')->will($this->returnValue($originalValue));
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getStoreLabel')->will($this->returnValue('Label'));
+        $attributeMock->expects($this->any())->method('getIsRequired')->will($this->returnValue($isRequired));
+
+        $this->model->setEntity($entityMock);
+        $this->model->setAttribute($attributeMock);
+        $this->assertEquals($expectedResult, $this->model->validateValue($value));
+    }
+
+    /**
+     * @return array
+     */
+    public function validateValueDataProvider()
+    {
+        return [
+            [
+                'value' => false,
+                'originalValue' => 'value',
+                'isRequired' => false,
+                'expectedResult' => true,
+            ],
+            [
+                'value' => false,
+                'originalValue' => null,
+                'isRequired' => true,
+                'expectedResult' => ['"Label" is a required value.'],
+            ],
+            [
+                'value' => false,
+                'originalValue' => null,
+                'isRequired' => false,
+                'expectedResult' => true,
+            ],
+            [
+                'value' => false,
+                'originalValue' => '0',
+                'isRequired' => true,
+                'expectedResult' => true,
+            ],
+            [
+                'value' => 'value',
+                'originalValue' => '',
+                'isRequired' => true,
+                'expectedResult' => true,
+            ]
+        ];
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Select::compactValue
+     */
+    public function testCompactValue()
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->once())->method('setData')->with('attrCode', 'value');
+
+        $attributeMock = $this->getMock('\Magento\Eav\Model\Attribute', [], [], '', false);
+        $attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('attrCode'));
+
+        $this->model->setAttribute($attributeMock);
+        $this->model->setEntity($entityMock);
+        $this->model->compactValue('value');
+    }
+
+    /**
+     * @covers \Magento\Eav\Model\Attribute\Data\Select::compactValue
+     */
+    public function testCompactValueWithFalseValue()
+    {
+        $entityMock = $this->getMock('\Magento\Framework\Model\AbstractModel', [], [], '', false);
+        $entityMock->expects($this->never())->method('setData');
+
+        $this->model->setEntity($entityMock);
+        $this->model->compactValue(false);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.ico b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.ico
new file mode 100644
index 0000000000000000000000000000000000000000..1e75a62598fe4f267e563abfbcf255da5984e6ab
Binary files /dev/null and b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.ico differ
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.jpg b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..f8e1802e54465b1b3c22ed78fe1514482e6d5e0d
Binary files /dev/null and b/dev/tests/unit/testsuite/Magento/Eav/Model/Attribute/Data/_files/image.jpg differ
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Frontend/DatetimeTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Frontend/DatetimeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..53dbcd665a23345845735869158a7cfcefc7e1e1
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Attribute/Frontend/DatetimeTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Entity\Attribute\Frontend;
+
+class DatetimeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $localeDateMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $booleanFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $attributeMock;
+
+    /**
+     * @var Datetime
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->booleanFactoryMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\Source\BooleanFactory',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->localeDateMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\TimezoneInterface');
+
+        $this->attributeMock = $this->getMock(
+            '\Magento\Eav\Model\Entity\Attribute\AbstractAttribute',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->attributeMock->expects($this->any())->method('getAttributeCode')->will($this->returnValue('datetime'));
+
+        $this->model = new Datetime($this->booleanFactoryMock, $this->localeDateMock);
+        $this->model->setAttribute($this->attributeMock);
+    }
+
+    public function testGetValue()
+    {
+        $attributeValue = '11-11-2011';
+        $dateFormat = 'dd-mm-yyyy';
+        $object = new \Magento\Framework\Object(array('datetime' => $attributeValue));
+        $this->attributeMock->expects($this->any())->method('getData')->with('frontend_input')
+            ->will($this->returnValue('text'));
+
+        $this->localeDateMock->expects($this->once())->method('getDateFormat')
+            ->with(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM)
+            ->will($this->returnValue($dateFormat));
+        $dateMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\DateInterface');
+        $dateMock->expects($this->once())->method('toString')->with($dateFormat)
+            ->will($this->returnValue($attributeValue));
+        $this->localeDateMock->expects($this->once())->method('date')
+            ->with($attributeValue, \Zend_Date::ISO_8601, null, false)
+            ->will($this->returnValue($dateMock));
+
+        $this->assertEquals($attributeValue, $this->model->getValue($object));
+    }
+
+    public function testGetValueWhenDateCannotBeRepresentedUsingIso8601()
+    {
+        $attributeValue = '11-11-2011';
+        $dateFormat = 'dd-mm-yyyy';
+        $object = new \Magento\Framework\Object(array('datetime' => $attributeValue));
+        $this->localeDateMock->expects($this->once())->method('getDateFormat')
+            ->with(\Magento\Framework\Stdlib\DateTime\TimezoneInterface::FORMAT_TYPE_MEDIUM)
+            ->will($this->returnValue($dateFormat));
+        $this->attributeMock->expects($this->any())->method('getData')->with('frontend_input')
+            ->will($this->returnValue('text'));
+
+        $dateMock = $this->getMock('\Magento\Framework\Stdlib\DateTime\DateInterface');
+        $dateMock->expects($this->once())->method('toString')->with($dateFormat)
+            ->will($this->returnValue($attributeValue));
+        $this->localeDateMock->expects($this->at(1))->method('date')
+            ->will($this->throwException(new \Exception('Wrong Date')));
+        $this->localeDateMock->expects($this->at(2))->method('date')
+            ->with($attributeValue, null, null, false)
+            ->will($this->returnValue($dateMock));
+
+        $this->assertEquals($attributeValue, $this->model->getValue($object));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/AlphanumTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/AlphanumTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..24fbd2e94331368b281c7a2b8ec9755a9bda2bef
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/AlphanumTest.php
@@ -0,0 +1,82 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Entity\Increment;
+
+class AlphanumTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Alphanum
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->model = new Alphanum();
+    }
+
+    public function testGetAllowedChars()
+    {
+        $this->assertEquals('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ', $this->model->getAllowedChars());
+    }
+
+    /**
+     * @param int $lastId
+     * @param string $prefix
+     * @param int|string $expectedResult
+     * @dataProvider getLastIdDataProvider
+     */
+    public function testGetNextId($lastId, $prefix, $expectedResult)
+    {
+        $this->model->setPrefix($prefix);
+        $this->model->setLastId($lastId);
+        $this->assertEquals($expectedResult, $this->model->getNextId());
+    }
+
+    public function getLastIdDataProvider()
+    {
+        return [
+            [
+                'lastId' => 'prefix00000001CZ',
+                'prefix' => 'prefix',
+                'expectedResult' => 'prefix00000001D0'
+            ],
+            [
+                'lastId' => 1,
+                'prefix' => 'prefix',
+                'expectedResult' => 'prefix00000002'
+            ],
+        ];
+    }
+
+    /**
+     * @expectedException \Magento\Eav\Exception
+     * @expectedExceptionMessage Invalid character encountered in increment ID: ---wrong-id---
+     */
+    public function testGetNextIdThrowsExceptionIfIdContainsNotAllowedCharacters()
+    {
+        $this->model->setLastId('---wrong-id---');
+        $this->model->setPrefix('prefix');
+        $this->model->getNextId();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/NumericTest.php b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/NumericTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba9c99838739347501aeaa3d4b6f652edd8c705c
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Eav/Model/Entity/Increment/NumericTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Eav\Model\Entity\Increment;
+
+class NumericTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Numeric
+     */
+    private $model;
+
+    protected function setUp()
+    {
+        $this->model = new Numeric();
+    }
+
+    /**
+     * @param int $lastId
+     * @param string $prefix
+     * @param int|string $expectedResult
+     * @dataProvider getLastIdDataProvider
+     */
+    public function testGetNextId($lastId, $prefix, $expectedResult)
+    {
+        $this->model->setLastId($lastId);
+        $this->model->setPrefix($prefix);
+        $this->assertEquals($expectedResult, $this->model->getNextId());
+    }
+
+    public function getLastIdDataProvider()
+    {
+        return [
+            [
+                'lastId' => 1,
+                'prefix' => 'prefix',
+                'expectedResult' => 'prefix00000002'
+            ],
+            [
+                'lastId' => 'prefix00000001',
+                'prefix' => 'prefix',
+                'expectedResult' => 'prefix00000002'
+            ],
+        ];
+    }
+
+    public function testGetPadLength()
+    {
+        $this->assertEquals(8, $this->model->getPadLength());
+        $this->model->setPadLength(10);
+        $this->assertEquals(10, $this->model->getPadLength());
+    }
+
+    public function getPadChar()
+    {
+        $this->assertEquals('0', $this->model->getPadChar());
+        $this->model->setPadChar('z');
+        $this->assertEquals('z', $this->model->getPadChar());
+    }
+
+    public function testFormat()
+    {
+        $this->model->setPrefix('prefix');
+        $this->model->setPadLength(3);
+        $this->model->setPadChar('z');
+        $this->assertEquals('prefixzz1', $this->model->format(1));
+    }
+
+    public function testFrontendFormat()
+    {
+        $this->assertEquals('value', $this->model->frontendFormat('value'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php b/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
index f9147a0e48aebcdb87af42ad01c2a8158d86470b..4e42620bbe51a11bde13dfcdef12527c1a91fcab 100644
--- a/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
+++ b/dev/tests/unit/testsuite/Magento/Email/Block/Adminhtml/Template/EditTest.php
@@ -71,7 +71,11 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $layoutMock = $this->getMock('Magento\Framework\View\Layout', array(), array(), '', false, false);
         $helperMock = $this->getMock('Magento\Backend\Helper\Data', array(), array(), '', false, false);
         $menuConfigMock = $this->getMock('Magento\Backend\Model\Menu\Config', array(), array(), '', false, false);
-        $menuMock = $this->getMock('Magento\Backend\Model\Menu', array(), array(), '', false, false);
+        $menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
         $menuItemMock = $this->getMock('Magento\Backend\Model\Menu\Item', array(), array(), '', false, false);
         $urlBuilder = $this->getMock('Magento\Backend\Model\Url', array(), array(), '', false, false);
         $this->_configStructureMock = $this->getMock(
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
index b9cc26b0518acbdc7fcd1b68f2c555a4c802bb70..6f753fe9727b77dddf45e45c8cc6db2557422c93 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Action/ActionTest.php
@@ -154,10 +154,6 @@ class ActionTest extends \PHPUnit_Framework_TestCase
             $this->returnValue(false)
         );
 
-        $this->_requestMock->expects($this->once())->method('getActionName')->will(
-            $this->returnValue(self::ACTION_NAME)
-        );
-
         // _forward expectations
         $this->_requestMock->expects($this->once())->method('initForward');
         $this->_requestMock->expects($this->once())->method('setParams')->with(self::$actionParams);
@@ -199,7 +195,7 @@ class ActionFake extends Action
     /**
      * Fake action to check a method call from a parent
      */
-    public function someactionAction()
+    public function execute()
     {
         $this->_forward(
             ActionTest::ACTION_NAME,
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/FrontControllerTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/FrontControllerTest.php
index 7813598ea34b73d77ba680a2bfdca292eea9f778..dab5ea93d21b576c5094f9c2dce114ee97e30788 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/FrontControllerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/FrontControllerTest.php
@@ -52,9 +52,7 @@ class FrontControllerTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['isDispatched', 'setDispatched', 'initForward', 'setActionName'])
             ->getMock();
 
-        $this->router = $this->getMockBuilder('Magento\Framework\App\Router\AbstractRouter')
-            ->disableOriginalConstructor()
-            ->getMock();
+        $this->router = $this->getMock('Magento\Framework\App\RouterInterface');
         $this->routerList = $this->getMock('Magento\Framework\App\RouterList', array(), array(), '', false);
         $this->model = new \Magento\Framework\App\FrontController($this->routerList);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/App/Router/DefaultRouterTest.php b/dev/tests/unit/testsuite/Magento/Framework/App/Router/DefaultRouterTest.php
index b0c02c2ebc82b917e5e1ca44924b1e4732f96b3e..313805eaa9ce89f3678a7feadd6575a8e72fb43f 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/App/Router/DefaultRouterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/App/Router/DefaultRouterTest.php
@@ -37,7 +37,7 @@ class DefaultRouterTest extends \PHPUnit_Framework_TestCase
         $request = $this->getMock('Magento\Framework\App\RequestInterface', [], [], '', false);
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $actionFactory = $this->getMock('Magento\Framework\App\ActionFactory', [], [], '', false);
-        $actionFactory->expects($this->once())->method('createController')->with(
+        $actionFactory->expects($this->once())->method('create')->with(
             'Magento\Framework\App\Action\Forward',
             array('request' => $request)
         )->will(
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php b/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
index e1b016a1bcd0c095081204e4a5a7e6bffb9cdeb1..5c4197d6d2bb7e1aac376de03c34584107a90e20 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Code/NameBuilderTest.php
@@ -49,13 +49,16 @@ class NameBuilderTest extends \PHPUnit_Framework_TestCase
 
     public function buildClassNameDataProvider()
     {
-        return array(
-            array(array('Checkout', 'Controller', 'Index'), 'Checkout\Controller\Index'),
-            array(array('checkout', 'controller', 'index'), 'Checkout\Controller\Index'),
-            array(
-                array('Magento_Backend', 'Block', 'urlrewrite', 'edit', 'form'),
+        return [
+            [['Checkout', 'Controller', 'Index'], 'Checkout\Controller\Index'],
+            [['checkout', 'controller', 'index'], 'Checkout\Controller\Index'],
+            [
+                ['Magento_Backend', 'Block', 'urlrewrite', 'edit', 'form'],
                 'Magento\Backend\Block\Urlrewrite\Edit\Form'
-            )
-        );
+            ],
+            [['MyNamespace', 'MyModule'], 'MyNamespace\MyModule'],
+            [['uc', 'words', 'test'], 'Uc\Words\Test'],
+            [['ALL', 'CAPS', 'TEST'], 'ALL\CAPS\TEST'],
+        ];
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/CollectionTest.php
index 7b06f27c6c92941aa80e496e180a19687e333224..dd6f900418aba9e1d5413dcbac6680edc65c00c0 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/CollectionTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/CollectionTest.php
@@ -46,6 +46,19 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
         $this->assertEmpty($this->_model->getItems());
     }
 
+    /**
+     * Test loadWithFilter()
+     * @return void
+     */
+    public function testLoadWithFilter()
+    {
+        $this->assertInstanceOf('Magento\Framework\Data\Collection', $this->_model->loadWithFilter());
+        $this->assertEmpty($this->_model->getItems());
+        $this->_model->addItem(new \Magento\Framework\Object());
+        $this->_model->addItem(new \Magento\Framework\Object());
+        $this->assertCount(2, $this->_model->loadWithFilter()->getItems());
+    }
+
     /**
      * @dataProvider setItemObjectClassDataProvider
      */
@@ -71,4 +84,100 @@ class CollectionTest extends \PHPUnit_Framework_TestCase
     {
         $this->_model->setItemObjectClass('Incorrect_ClassName');
     }
+
+    public function testAddFilter()
+    {
+        $this->_model->addFilter('field1', 'value');
+        $this->assertEquals('field1', $this->_model->getFilter('field1')->getData('field'));
+    }
+
+    public function testGetFilters()
+    {
+        $this->_model->addFilter('field1', 'value');
+        $this->_model->addFilter('field2', 'value');
+        $this->assertEquals('field1', $this->_model->getFilter(['field1', 'field2'])[0]->getData('field'));
+        $this->assertEquals('field2', $this->_model->getFilter(['field1', 'field2'])[1]->getData('field'));
+    }
+
+    public function testGetNonExistingFilters()
+    {
+        $this->assertEmpty($this->_model->getFilter([]));
+        $this->assertEmpty($this->_model->getFilter('non_existing_filter'));
+    }
+
+    public function testFlag()
+    {
+        $this->_model->setFlag('flag_name', 'flag_value');
+        $this->assertEquals('flag_value', $this->_model->getFlag('flag_name'));
+        $this->assertTrue($this->_model->hasFlag('flag_name'));
+        $this->assertNull($this->_model->getFlag('non_existing_flag'));
+    }
+
+
+    public function testGetCurPage()
+    {
+        $this->_model->setCurPage(10);
+        $this->assertEquals(1, $this->_model->getCurPage());
+    }
+
+    public function testPossibleFlowWithItem()
+    {
+        $firstItemMock = $this->getMock('Magento\Framework\Object', [], [], '', false);
+        $secondItemMock = $this->getMock('Magento\Framework\Object', [], [], '', false);
+        $requiredFields = ['required_field_one', 'required_field_two'];
+        $arrItems = [
+            'totalRecords' => 1,
+            'items' => [
+                0 => 'value'
+            ]
+        ];
+        $items = [
+            'item_id' => $firstItemMock,
+            0 => $secondItemMock
+        ];
+        $firstItemMock->expects($this->exactly(2))->method('getId')->will($this->returnValue('item_id'));
+
+        $firstItemMock
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->with('colName')
+            ->will($this->returnValue('first_value'));
+        $secondItemMock
+            ->expects($this->atLeastOnce())
+            ->method('getData')
+            ->with('colName')
+            ->will($this->returnValue('second_value'));
+
+        $firstItemMock
+            ->expects($this->once())
+            ->method('toArray')
+            ->with($requiredFields)
+            ->will($this->returnValue('value'));
+        /** add items and set them values */
+        $this->_model->addItem($firstItemMock);
+        $this->assertEquals($arrItems, $this->_model->toArray($requiredFields));
+
+        $this->_model->addItem($secondItemMock);
+        $this->_model->setDataToAll('column', 'value');
+
+        /** get items by column name */
+        $this->assertEquals(['first_value', 'second_value'], $this->_model->getColumnValues('colName'));
+        $this->assertEquals([$secondItemMock], $this->_model->getItemsByColumnValue('colName', 'second_value'));
+        $this->assertEquals($firstItemMock, $this->_model->getItemByColumnValue('colName', 'second_value'));
+        $this->assertEquals([], $this->_model->getItemsByColumnValue('colName', 'non_existing_value'));
+        $this->assertEquals(null, $this->_model->getItemByColumnValue('colName', 'non_existing_value'));
+
+        /** get items */
+        $this->assertEquals(['item_id', 0], $this->_model->getAllIds());
+        $this->assertEquals($firstItemMock, $this->_model->getFirstItem());
+        $this->assertEquals($secondItemMock, $this->_model->getLastItem());
+        $this->assertEquals($items, $this->_model->getItems('item_id'));
+
+        /** remove existing items */
+        $this->assertNull($this->_model->getItemById('not_existing_item_id'));
+        $this->_model->removeItemByKey('item_id');
+        $this->assertEquals([$secondItemMock], $this->_model->getItems());
+        $this->_model->removeAllItems();
+        $this->assertEquals([], $this->_model->getItems());
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Form/AbstractFormTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/AbstractFormTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..38f8a059cc7da9d3e48fa00a0bc5038123b26db8
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/AbstractFormTest.php
@@ -0,0 +1,148 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Data\Form;
+
+
+class AbstractFormTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $factoryElementMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $factoryCollectionMock;
+
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $elementMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $allElementsMock;
+    /**
+     * @var \Magento\Framework\Data\Form
+     */
+
+    /**
+     * @var \Magento\Framework\Data\Form\AbstractForm
+     */
+    protected $abstractForm;
+
+    protected function setUp()
+    {
+        $this->factoryElementMock = $this->getMock(
+            'Magento\Framework\Data\Form\Element\Factory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $this->factoryCollectionMock = $this->getMock(
+            'Magento\Framework\Data\Form\Element\CollectionFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $this->allElementsMock =
+            $this->getMock('Magento\Framework\Data\Form\Element\Collection', [], [], '', false);
+        $this->elementMock =
+            $this->getMock('Magento\Framework\Data\Form\Element\AbstractElement', [], [], '', false);
+
+        $this->abstractForm = new AbstractForm($this->factoryElementMock, $this->factoryCollectionMock, array());
+    }
+
+    public function testAddElement()
+    {
+        $this->factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->elementMock->expects($this->once())->method('setForm');
+        $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock, false);
+        $this->abstractForm->addElement($this->elementMock, false);
+    }
+
+    public function testAddField()
+    {
+        $config = ['name' => 'store_type', 'no_span' => true, 'value' => 'value'];
+        $this->factoryElementMock
+            ->expects($this->once())
+            ->method('create')
+            ->with('hidden', ['data' => $config])
+            ->will($this->returnValue($this->elementMock));
+        $this->elementMock->expects($this->once())->method('setId')->with('store_type');
+        $this->factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock, false);
+        $this->assertEquals($this->elementMock, $this->abstractForm->addField('store_type', 'hidden', $config));
+        $this->abstractForm->removeField('hidden');
+    }
+
+    public function testAddFieldset()
+    {
+        $config = ['name' => 'store_type', 'no_span' => true, 'value' => 'value'];
+        $this->factoryElementMock
+            ->expects($this->once())
+            ->method('create')
+            ->with('fieldset', ['data' => $config])
+            ->will($this->returnValue($this->elementMock));
+        $this->elementMock->expects($this->once())->method('setId')->with('hidden');
+        $this->elementMock->expects($this->once())->method('setAdvanced')->with(false);
+        $this->elementMock->expects($this->once())->method('setForm');
+        $this->factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock, false);
+        $this->abstractForm->addFieldset('hidden', $config);
+    }
+
+    public function testAddColumn()
+    {
+        $config = ['name' => 'store_type', 'no_span' => true, 'value' => 'value'];
+        $this->factoryElementMock
+            ->expects($this->once())
+            ->method('create')
+            ->with('column', ['data' => $config])
+            ->will($this->returnValue($this->elementMock));
+        $this->elementMock->expects($this->once())->method('setId')->with('hidden');
+        $this->elementMock->expects($this->exactly(2))->method('setForm')->will($this->returnSelf());
+        $this->factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock, false);
+        $this->abstractForm->addColumn('hidden', $config);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Form/Element/DateTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
index 87b5860c8ee356157e2a9dee9a2c0997430505cb..c538eca673609d27b590206211fbb294a7f5a3e6 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/Element/DateTest.php
@@ -107,13 +107,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
     protected function getFormMock($exactly)
     {
         $functions = array('getFieldNameSuffix', 'getHtmlIdPrefix', 'getHtmlIdSuffix');
-        $formMock = $this->getMock(
-            'stdClass',
-            $functions,
-            array(),
-            '',
-            false
-        );
+        $formMock = $this->getMock('stdClass', $functions);
         foreach ($functions as $method) {
             switch($exactly) {
                 case 'once':
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Form/FormKeyTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/FormKeyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7ed9ef41976671ac4b922246ee2456d73e133fa
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Form/FormKeyTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Data\Form;
+
+use Magento\Framework\Data\Form;
+
+class FormKeyTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $mathRandomMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionMock;
+
+    /**
+     * @var \Magento\Framework\Data\Form\FormKey
+     */
+    protected $formKey;
+
+    protected function setUp()
+    {
+        $this->mathRandomMock = $this->getMock('Magento\Framework\Math\Random', [], [], '', false);
+        $methods = ['setData', 'getData'];
+        $this->sessionMock = $this->getMock('Magento\Framework\Session\SessionManager', $methods, [], '', false);
+        $this->formKey = new FormKey(
+            $this->mathRandomMock,
+            $this->sessionMock
+        );
+    }
+
+    public function testGetFormKeyNotExist()
+    {
+        $valueMap = [
+            [FormKey::FORM_KEY, false, null],
+            [FormKey::FORM_KEY, false, 'random_string']
+        ];
+        $this->sessionMock
+            ->expects($this->any())
+            ->method('getData')
+            ->will($this->returnValueMap($valueMap));
+        $this->mathRandomMock
+            ->expects($this->once())
+            ->method('getRandomString')
+            ->with(16)
+            ->will($this->returnValue('random_string'));
+        $this->sessionMock->expects($this->once())->method('setData')->with(FormKey::FORM_KEY, 'random_string');
+        $this->formKey->getFormKey();
+    }
+
+    public function testGetFormKeyExists()
+    {
+        $this->sessionMock
+            ->expects($this->exactly(2))
+            ->method('getData')
+            ->with(FormKey::FORM_KEY)
+            ->will($this->returnValue('random_string'));
+        $this->mathRandomMock
+            ->expects($this->never())
+            ->method('getRandomString');
+        $this->sessionMock->expects($this->never())->method('setData');
+        $this->assertEquals('random_string', $this->formKey->getFormKey());
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php
index 402f010c253656a051eeb3f9607285bb7970cc93..fe9ecdb6f425748129db6dd82181d17524f9852b 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/FormTest.php
@@ -44,6 +44,15 @@ class FormTest extends \PHPUnit_Framework_TestCase
      */
     protected $_formKeyMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $elementMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $allElementsMock;
     /**
      * @var \Magento\Framework\Data\Form
      */
@@ -65,7 +74,8 @@ class FormTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $this->_factoryCollectionMock->expects($this->any())->method('create')->will($this->returnValue(array()));
+        $this->allElementsMock =
+            $this->getMock('Magento\Framework\Data\Form\Element\Collection', [], [], '', false);
         $this->_formKeyMock = $this->getMock(
             'Magento\Framework\Data\Form\FormKey',
             array('getFormKey'),
@@ -73,12 +83,19 @@ class FormTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $methods = ['getId', 'setValue', 'setName', 'getName', '_wakeup'];
+        $this->elementMock =
+            $this->getMock('Magento\Framework\Data\Form\Element\AbstractElement', $methods, [], '', false);
 
         $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock);
     }
 
     public function testFormKeyUsing()
     {
+        $this->_factoryCollectionMock
+            ->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue(array()));
         $formKey = 'form-key';
         $this->_formKeyMock->expects($this->once())->method('getFormKey')->will($this->returnValue($formKey));
 
@@ -86,4 +103,75 @@ class FormTest extends \PHPUnit_Framework_TestCase
         $this->_form->setMethod('post');
         $this->assertContains($formKey, $this->_form->toHtml());
     }
+
+    public function testAddValue()
+    {
+        $this->_factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock);
+        $values = [
+            'element_id' => 'value_one'
+        ];
+        $this->elementMock->expects($this->once())->method('getId')->will($this->returnValue('element_id'));
+        $this->allElementsMock->expects($this->once())->method('add')->with($this->elementMock);
+        $this->elementMock->expects($this->once())->method('setValue')->with('value_one');
+        $this->_form->addElementToCollection($this->elementMock);
+        $this->_form->addValues($values);
+    }
+
+    /**
+     * @param int $number
+     * @param string $elementId
+     * @param string|null $value
+     *
+     * @dataProvider setValueDataProvider
+     */
+    public function testSetValue($number, $elementId, $value)
+    {
+        $this->_factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue(array($this->elementMock)));
+        $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock);
+        $values = [
+            'element_two' => 'value_two'
+        ];
+        $this->elementMock->expects($this->exactly($number))->method('getId')->will($this->returnValue($elementId));
+        $this->elementMock->expects($this->once())->method('setValue')->with($value);
+        $this->_form->setValues($values);
+    }
+
+    public function setValueDataProvider()
+    {
+        return [
+            'value_exists' => [2, 'element_two', 'value_two'],
+            'value_not_exist' => [1, 'element_one', null]
+        ];
+    }
+
+    public function testAddFieldNameSuffix()
+    {
+        $this->_factoryCollectionMock
+            ->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue(array($this->elementMock)));
+        $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock);
+        $this->elementMock->expects($this->once())->method('getName')->will($this->returnValue('name'));
+        $this->elementMock->expects($this->once())->method('setName')->with('_suffix[name]');
+        $this->_form->addFieldNameSuffix('_suffix');
+    }
+
+    public function testAddEllement()
+    {
+        $this->_factoryCollectionMock
+            ->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($this->allElementsMock));
+        $this->_form = new Form($this->_factoryElementMock, $this->_factoryCollectionMock, $this->_formKeyMock);
+        $this->elementMock->expects($this->any())->method('getId')->will($this->returnValue('element_id'));
+        $this->allElementsMock->expects($this->exactly(2))->method('add')->with($this->elementMock, false);
+        $this->_form->addElement($this->elementMock);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php b/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..afe8ae8c7df5a0a263fc21ce283ecf9f0e10d2c7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Data/Tree/Node/CollectionTest.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Data\Tree\Node;
+
+class CollectionTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Data\Tree\Node\Collection
+     */
+    protected $collection;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $containerMock;
+
+    protected function setUp()
+    {
+        $this->containerMock = $this->getMock('Magento\Framework\Data\Tree\Node', [], [], '', false);
+        $this->collection = new \Magento\Framework\Data\Tree\Node\Collection($this->containerMock);
+    }
+
+    /**
+     * @param int $number
+     * @param \PHPUnit_Framework_MockObject_MockObject|null $returnValue
+     *
+     * @dataProvider testAddDataProvider
+     */
+    public function testAdd($number, $returnValue)
+    {
+        $nodeMock = $this->getMock('Magento\Framework\Data\Tree\Node', [], [], '', false);
+        $nodeMock->expects($this->once())->method('setParent')->with($this->containerMock);
+        $this->containerMock
+            ->expects($this->exactly($number))
+            ->method('getTree')
+            ->will($this->returnValue($returnValue));
+        $nodeMock->expects($this->once())->method('getId')->will($this->returnValue('id_node'));
+        $this->assertEquals($nodeMock, $this->collection->add($nodeMock));
+        $this->assertEquals(['id_node' => $nodeMock], $this->collection->getNodes());
+        $this->assertEquals($nodeMock, $this->collection->searchById('id_node'));
+        $this->assertEquals(null, $this->collection->searchById('id_node_new'));
+    }
+
+    public function testAddDataProvider()
+    {
+        return [
+            'tree_exists' => [2, $this->getMock('Magento\Framework\Data\Tree', [], [], '', false)],
+            'tree_not_exist' => [1, null]
+        ];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Image/AdapterFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/Image/AdapterFactoryTest.php
index a4475b444ff50fa808857fe04811a4d9b5b03d2a..c7255d72573de856c187015851fd9e7aed33f5e1 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Image/AdapterFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Image/AdapterFactoryTest.php
@@ -190,7 +190,7 @@ class AdapterFactoryTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $imageAdapterMock = $this->getMock($class, array('checkDependencies'), array(), '', false);
+        $imageAdapterMock = $this->getMock($class, array('checkDependencies'));
 
         $objectManagerMock->expects(
             $this->once()
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Locale/ListsTest.php b/dev/tests/unit/testsuite/Magento/Framework/Locale/ListsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1375f86eaace235ab65879ecc2042dedb8f59c40
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/Locale/ListsTest.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Framework\Locale;
+
+class ListsTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\Locale\Lists
+     */
+    protected $listsModel;
+
+    /**
+     * @var  \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\State
+     */
+    protected $mockAppState;
+
+    /**
+     * @var  \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\App\ScopeResolverInterface
+     */
+    protected $mockScopeResolver;
+
+    /**
+     * @var  \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ConfigInterface
+     */
+    protected $mockConfig;
+
+    /**
+     * @var  \PHPUnit_Framework_MockObject_MockObject | \Magento\Framework\Locale\ResolverInterface
+     */
+    protected $mockLocaleResolver;
+
+    protected function setUp()
+    {
+        $this->mockAppState = $this->getMockBuilder('\Magento\Framework\App\State')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->mockScopeResolver = $this->getMockBuilder('\Magento\Framework\App\ScopeResolverInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->mockConfig = $this->getMockBuilder('\Magento\Framework\Locale\ConfigInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->mockLocaleResolver = $this->getMockBuilder('\Magento\Framework\Locale\ResolverInterface')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $locale = "some_locale";
+        $this->mockLocaleResolver->expects($this->atLeastOnce())
+            ->method('setLocale')
+            ->with($locale);
+
+        $this->listsModel = new \Magento\Framework\Locale\Lists(
+            $this->mockAppState,
+            $this->mockScopeResolver,
+            $this->mockConfig,
+            $this->mockLocaleResolver,
+            $locale
+        );
+    }
+
+    public function testGetCountryTranslationList()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->once())
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        // clearly english results
+        $expectedResults = [
+            'AD' => 'Andorra',
+            'ZZ' => 'Unknown or Invalid Region',
+            'VC' => 'Saint Vincent and the Grenadines',
+            'PU' => 'U.S. Miscellaneous Pacific Islands'
+        ];
+
+        $countryTranslationList = $this->listsModel->getCountryTranslationList();
+        foreach ($expectedResults as $key => $value) {
+            $this->assertArrayHasKey($key, $countryTranslationList);
+            $this->assertEquals($value, $countryTranslationList[$key]);
+        }
+    }
+
+    public function testGetCountryTranslation()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->once())
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $this->assertFalse($this->listsModel->getCountryTranslation(null));
+    }
+
+    public function testGetTranslationList()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->exactly(2))
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $path = 'territory';
+        $value = 2;
+
+        // clearly english results
+        $expectedResults = [
+            'AD' => 'Andorra',
+            'ZZ' => 'Unknown or Invalid Region',
+            'VC' => 'Saint Vincent and the Grenadines',
+            'PU' => 'U.S. Miscellaneous Pacific Islands'
+        ];
+
+        $countryTranslationList = $this->listsModel->getTranslationList($path, $value);
+        foreach ($expectedResults as $key => $value) {
+            $this->assertArrayHasKey($key, $countryTranslationList);
+            $this->assertEquals($value, $countryTranslationList[$key]);
+        }
+    }
+
+    public function testGetOptionAllCurrencies()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->exactly(2))
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        // clearly English results
+        $expectedResults = [
+            ['value' => 'BAM', 'label' => 'Bosnia-Herzegovina Convertible Mark'],
+            ['value' => 'TTD', 'label' => 'Trinidad and Tobago Dollar'],
+            ['value' => 'USN', 'label' => 'US Dollar (Next day)'],
+            ['value' => 'USS', 'label' => 'US Dollar (Same day)']
+        ];
+
+        $currencyList = $this->listsModel->getOptionAllCurrencies();
+        foreach ($expectedResults as $value) {
+            $this->assertContains($value, $currencyList);
+        }
+    }
+
+    public function testGetOptionCurrencies()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->exactly(2))
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $this->mockAppState->expects($this->once())
+            ->method('isInstalled')
+            ->will($this->returnValue(false));
+
+        $allowedCurrencies = ['USD', 'GBP', 'EUR'];
+
+        $this->mockConfig->expects($this->once())
+            ->method('getAllowedCurrencies')
+            ->will($this->returnValue($allowedCurrencies));
+
+        $expectedArray = [
+            ['value' => 'GBP', 'label' => 'British Pound Sterling'],
+            ['value' => 'EUR', 'label' => 'Euro'],
+            ['value' => 'USD', 'label' => 'US Dollar'],
+        ];
+
+        $this->assertSame($expectedArray, $this->listsModel->getOptionCurrencies());
+    }
+
+    public function testGetOptionCountries()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->once())
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        // clearly English results
+        $expectedResults = [
+            ['value' => 'AG', 'label' => 'Antigua and Barbuda'],
+            ['value' => 'BA', 'label' => 'Bosnia and Herzegovina'],
+            ['value' => 'CT', 'label' => 'Canton and Enderbury Islands'],
+            ['value' => 'GS', 'label' => 'South Georgia and the South Sandwich Islands'],
+            ['value' => 'PU', 'label' => 'U.S. Miscellaneous Pacific Islands']
+        ];
+
+        $optionCountries = $this->listsModel->getOptionCountries();
+        foreach ($expectedResults as $value) {
+            $this->assertContains($value, $optionCountries);
+        }
+    }
+
+    public function testGetOptionsWeekdays()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->exactly(2))
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $expectedArray = [
+            ['label' => 'Sunday', 'value' => 'Sun'],
+            ['label' => 'Monday', 'value' => 'Mon'],
+            ['label' => 'Tuesday', 'value' => 'Tue'],
+            ['label' => 'Wednesday', 'value' => 'Wed'],
+            ['label' => 'Thursday', 'value' => 'Thu'],
+            ['label' => 'Friday', 'value' => 'Fri'],
+            ['label' => 'Saturday', 'value' => 'Sat'],
+        ];
+
+        $this->assertEquals($expectedArray, $this->listsModel->getOptionWeekdays(true, true));
+    }
+
+    public function testGetOptionTimezones()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->exactly(2))
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $expectedResults = [
+            ['value' => 'Australia/Darwin', 'label' => 'AUS Central Standard Time (Australia/Darwin)'],
+            ['value' => 'Asia/Jerusalem', 'label' => 'Israel Standard Time (Asia/Jerusalem)'],
+            ['value' => 'Asia/Yakutsk', 'label' => 'Yakutsk Standard Time (Asia/Yakutsk)'],
+        ];
+
+        $timeZones = $this->listsModel->getOptionTimezones();
+        foreach ($expectedResults as $value) {
+            $this->assertContains($value, $timeZones);
+        }
+    }
+
+    public function testGetOptionLocales()
+    {
+        $this->setupForOptionLocales();
+
+        $this->assertEquals(
+            [['value' => 'en_US', 'label' => 'English (United States)']],
+            $this->listsModel->getOptionLocales()
+        );
+    }
+
+    public function testGetTranslatedOptionLocales()
+    {
+        $this->setupForOptionLocales();
+
+        $this->assertEquals(
+            [['value' => 'en_US', 'label' => 'English (United States) / English (United States)']],
+            $this->listsModel->getTranslatedOptionLocales()
+        );
+    }
+
+    /**
+     * @return \Magento\Framework\LocaleInterface
+     */
+    protected function setupForOptionLocales()
+    {
+        $locale = new \Magento\Framework\Locale('en');
+
+        $this->mockLocaleResolver->expects($this->any())
+            ->method('getLocale')
+            ->will($this->returnValue($locale));
+
+        $allowedLocales = ['en_US'];
+        $this->mockConfig->expects($this->once())
+            ->method('getAllowedLocales')
+            ->will($this->returnValue($allowedLocales));
+
+        return $locale;
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Session/SaveHandlerFactoryTest.php b/dev/tests/unit/testsuite/Magento/Framework/Session/SaveHandlerFactoryTest.php
index 7fee03770e83beaa3810ed2e424beef39b77ceb6..a0e21218890d8c752aa65857b58a151d2fcff144 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Session/SaveHandlerFactoryTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Session/SaveHandlerFactoryTest.php
@@ -30,7 +30,7 @@ class SaveHandlerFactoryTest extends \PHPUnit_Framework_TestCase
      */
     public function testCreate($handlers, $saveClass, $saveMethod)
     {
-        $saveHandler = $this->getMock($saveClass, array(), array(), '', false);
+        $saveHandler = $this->getMock($saveClass);
         $objectManager = $this->getMock(
             '\Magento\Framework\ObjectManager\ObjectManager',
             array('create'),
diff --git a/dev/tests/unit/testsuite/Magento/Framework/Translate/InlineTest.php b/dev/tests/unit/testsuite/Magento/Framework/Translate/InlineTest.php
index 08e2ab8cbf7ac6255307adf3f117d361069d3ec0..74ca103dc866b0d76c9851dac1611f712a9d3611 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/Translate/InlineTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/Translate/InlineTest.php
@@ -182,9 +182,8 @@ class InlineTest extends \PHPUnit_Framework_TestCase
     public function testProcessResponseBody($scope, $body, $expected)
     {
         $isJson = true;
-        if ($scope == 'admin') {
-            $this->prepareIsAllowed(true, true, true, $scope);
-        }
+        $this->prepareIsAllowed(true, true, true, $scope);
+
         $jsonCall = is_array($body) ? 2 * (count($body) + 1)  : 2;
         $this->parserMock->expects(
             $this->exactly($jsonCall)
@@ -245,9 +244,8 @@ class InlineTest extends \PHPUnit_Framework_TestCase
     public function testProcessResponseBodyGetInlineScript($scope, $body, $expected)
     {
         $isJson = true;
-        if ($scope == 'admin') {
-            $this->prepareIsAllowed(true, true, true, $scope);
-        }
+        $this->prepareIsAllowed(true, true, true, $scope);
+
         $jsonCall = is_array($body) ? 2 * (count($body) + 1)  : 2;
         $this->parserMock->expects(
             $this->exactly($jsonCall)
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeModularTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeModularTest.php
index e8f69c18aece7981b82acf70d35220e217a94e14..f4c468b43a31e30104ad9c8f786b540729c7abe6 100644
--- a/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeModularTest.php
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeModularTest.php
@@ -24,8 +24,8 @@
 
 namespace Magento\Framework\View\File\Collector;
 
-use Magento\Framework\Filesystem\Directory\Read,
-    Magento\Framework\View\File\Factory;
+use Magento\Framework\Filesystem\Directory\Read;
+use Magento\Framework\View\File\Factory;
 
 class ThemeModularTest extends \PHPUnit_Framework_TestCase
 {
@@ -48,10 +48,17 @@ class ThemeModularTest extends \PHPUnit_Framework_TestCase
     {
         $this->directory = $this->getMock(
             'Magento\Framework\Filesystem\Directory\Read',
-            array('getAbsolutePath', 'search'), array(), '', false
+            array('getAbsolutePath', 'search'),
+            array(),
+            '',
+            false
         );
         $filesystem = $this->getMock(
-            'Magento\Framework\App\Filesystem', array('getDirectoryRead', '__wakeup'), array(), '', false
+            'Magento\Framework\App\Filesystem',
+            array('getDirectoryRead', '__wakeup'),
+            array(),
+            '',
+            false
         );
         $filesystem->expects($this->once())
             ->method('getDirectoryRead')
@@ -59,7 +66,9 @@ class ThemeModularTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($this->directory));
         $this->fileFactory = $this->getMock('Magento\Framework\View\File\Factory', array(), array(), '', false);
         $this->model = new \Magento\Framework\View\File\Collector\ThemeModular(
-            $filesystem, $this->fileFactory, 'subdir'
+            $filesystem,
+            $this->fileFactory,
+            'subdir'
         );
     }
 
diff --git a/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeTest.php b/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bd0fe28b290c988c9a6a7a631c19207420010ea
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Framework/View/File/Collector/ThemeTest.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\View\File\Collector;
+
+use Magento\Framework\View\File\Factory;
+
+/**
+ * Tests Theme
+ */
+class ThemeTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\Filesystem|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filesystemMock;
+
+    /**
+     * @var Factory|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $fileFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Filesystem\Directory\ReadInterface|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $themesDirectoryMock;
+
+    /**
+     * @var \Magento\Framework\View\Design\ThemeInterface|PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $themeMock;
+
+    public function setup()
+    {
+        $this->filesystemMock = $this->getMockBuilder('Magento\Framework\App\Filesystem')
+            ->disableOriginalConstructor()->getMock();
+
+        $this->themesDirectoryMock = $this->getMockBuilder('Magento\Framework\Filesystem\Directory\ReadInterface')
+            ->getMock();
+        $this->filesystemMock->expects($this->any())->method('getDirectoryRead')
+            ->will($this->returnValue($this->themesDirectoryMock));
+
+        $this->fileFactoryMock = $this->getMockBuilder('Magento\Framework\View\File\Factory')
+            ->disableOriginalConstructor()->getMock();
+
+        $this->themeMock = $this->getMockBuilder('Magento\Framework\View\Design\ThemeInterface')->getMock();
+    }
+
+    public function testGetFilesEmpty()
+    {
+        $this->themesDirectoryMock->expects($this->any())->method('search')->will($this->returnValue([]));
+        $theme = new Theme(
+            $this->filesystemMock,
+            $this->fileFactoryMock
+        );
+
+        // Verify no files were returned
+        $this->assertEquals([], $theme->getFiles($this->themeMock, ''));
+    }
+
+    public function testGetFilesSingle()
+    {
+        $filePath = '/opt/magento2/app/design/frontend/Magento/blank/Magento_Customer/css/something.less';
+        $this->themesDirectoryMock->expects($this->once())
+            ->method('search')
+            ->will($this->returnValue(['file']));
+        $this->themesDirectoryMock->expects($this->once())
+            ->method('getAbsolutePath')
+            ->with('file')
+            ->will($this->returnValue($filePath));
+
+        $fileMock = $this->getMockBuilder('Magento\Framework\View\Layout\File')
+            ->getMock();
+
+        $this->fileFactoryMock->expects($this->once())
+            ->method('create')
+            ->with($this->equalTo($filePath), null, $this->themeMock)
+            ->will($this->returnValue($fileMock));
+
+        $theme = new Theme(
+            $this->filesystemMock,
+            $this->fileFactoryMock
+        );
+
+        // One file was returned from search
+        $this->assertEquals([$fileMock], $theme->getFiles($this->themeMock, 'css/*.less'));
+    }
+
+    public function testGetFilesMultiple()
+    {
+        $dirPath = '/Magento_Customer/css/';
+        $themePath = '/opt/magento2/app/design/frontend/Magento/blank';
+        $searchPath = 'css/*.test';
+        $this->themeMock->expects($this->any())->method('getFullPath')
+            ->will($this->returnValue($themePath));
+
+        $this->themesDirectoryMock->expects($this->any())
+            ->method('getAbsolutePath')
+            ->will(
+                $this->returnValueMap(
+                    [
+                        ['fileA.test', $dirPath . 'fileA.test'],
+                        ['fileB.tst', $dirPath . 'fileB.tst'],
+                        ['fileC.test', $dirPath . 'fileC.test'],
+                    ]
+                )
+            );
+
+        $fileMock = $this->getMockBuilder('Magento\Framework\View\Layout\File')
+            ->getMock();
+
+        // Verifies correct files are searched for
+        $this->themesDirectoryMock->expects($this->once())
+            ->method('search')
+            ->with($themePath. '/' . $searchPath)
+            ->will($this->returnValue(['fileA.test', 'fileC.test']));
+
+        // Verifies Magento_Customer was correctly produced from directory path
+        $this->fileFactoryMock->expects($this->any())
+            ->method('create')
+            ->with($this->isType('string'), null, $this->equalTo($this->themeMock))
+            ->will($this->returnValue($fileMock));
+
+        $theme = new Theme(
+            $this->filesystemMock,
+            $this->fileFactoryMock
+        );
+        // Only two files should be in array, which were returned from search
+        $this->assertEquals([$fileMock, $fileMock], $theme->getFiles($this->themeMock, 'css/*.test'));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/GroupedTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/GroupedTest.php
index 1c40743fbd9ed0baf3cadc2e4ff89e528ca8d302..925c51ffed6f83c0f9d8812bb92412849240ece2 100644
--- a/dev/tests/unit/testsuite/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/GroupedTest.php
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Block/Adminhtml/Product/Composite/Fieldset/GroupedTest.php
@@ -68,12 +68,6 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->getMock();
         $customerMock->expects($this->any())->method('getId')->will($this->returnValue(1));
 
-        $priceHelperMock = $this->getMockBuilder(
-            'Magento\Catalog\Helper\Product\Price'
-        )->disableOriginalConstructor()->getMock();
-
-        $priceHelperMock->expects($this->any())->method('getCustomer')->will($this->returnValue($customerMock));
-
         $objectHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->block = $objectHelper->getObject(
             'Magento\GroupedProduct\Block\Adminhtml\Product\Composite\Fieldset\Grouped',
@@ -81,7 +75,6 @@ class GroupedTest extends \PHPUnit_Framework_TestCase
                 'registry' => $this->registryMock,
                 'storeManager' => $this->storeManagerMock,
                 'coreHelper' => $this->coreHelperMock,
-                'priceHelper' => $priceHelperMock,
                 'data' => array('product' => $this->productMock)
             )
         );
diff --git a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/EditTest.php b/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
similarity index 92%
rename from dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/EditTest.php
rename to dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
index cae850c0aad744ddbfdcf842671ee5de8d5e7536..4ee85424c37b1588e2efe3dcfb9de2e122892480 100644
--- a/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/EditTest.php
+++ b/dev/tests/unit/testsuite/Magento/GroupedProduct/Controller/Adminhtml/Edit/PopupTest.php
@@ -21,9 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\GroupedProduct\Controller\Adminhtml;
+namespace Magento\GroupedProduct\Controller\Adminhtml\Edit;
 
-class EditTest extends \PHPUnit_Framework_TestCase
+class PopupTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\TestFramework\Helper\ObjectManager
@@ -31,9 +31,9 @@ class EditTest extends \PHPUnit_Framework_TestCase
     protected $objectManager;
 
     /**
-     * @var \Magento\GroupedProduct\Controller\Adminhtml\Edit
+     * @var \Magento\GroupedProduct\Controller\Adminhtml\Edit\Popup
      */
-    protected $controller;
+    protected $action;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
@@ -63,8 +63,8 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $this->view = $this->getMock('Magento\Framework\App\ViewInterface', array(), array(), '', false);
 
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $this->controller = $this->objectManager->getObject(
-            '\Magento\GroupedProduct\Controller\Adminhtml\Edit',
+        $this->action = $this->objectManager->getObject(
+            '\Magento\GroupedProduct\Controller\Adminhtml\Edit\Popup',
             array(
                 'request' => $this->request,
                 'factory' => $this->factory,
@@ -111,7 +111,7 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $this->view->expects($this->once())->method('loadLayout')->with(false);
         $this->view->expects($this->once())->method('renderLayout');
 
-        $this->controller->popupAction();
+        $this->action->execute();
     }
 
     public function testPopupActionWithProductIdNoSetId()
@@ -151,6 +151,6 @@ class EditTest extends \PHPUnit_Framework_TestCase
         $this->view->expects($this->once())->method('loadLayout')->with(false);
         $this->view->expects($this->once())->method('renderLayout');
 
-        $this->controller->popupAction();
+        $this->action->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php
index 77634d3f9e3cb0ea245398699ec80b520c4faa00..59159a54d48efa34e19bb785f10c988efc22dfe1 100644
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php
+++ b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.php
@@ -27,8 +27,4 @@ return array(
         'instance' => 'Magento\CatalogInventory\Model\Indexer\Stock',
         'depends' => array()
     ),
-    'catalog_product_attribute' => array(
-        'name' => 'catalog_product_attribute',
-        'depends' => array('cataloginventory_stock')
-    )
 );
diff --git a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml
index b3ace70abe8ea291e4b04d770471c1082be415a5..af7a39aee6a8db4407c073ec2fbb163d7da2cafe 100644
--- a/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml
+++ b/dev/tests/unit/testsuite/Magento/Index/Model/Indexer/Config/_files/indexers.xml
@@ -25,7 +25,4 @@
 -->
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../../../../app/code/Magento/Index/etc/indexers.xsd">
     <indexer name="cataloginventory_stock" instance="Magento\CatalogInventory\Model\Indexer\Stock" />
-    <indexer name="catalog_product_attribute">
-        <depends name="cataloginventory_stock" />
-    </indexer>
 </config>
diff --git a/dev/tests/unit/testsuite/Magento/Install/App/Action/Plugin/DirTest.php b/dev/tests/unit/testsuite/Magento/Install/App/Action/Plugin/DirTest.php
index 53bfa04139af5b24be39e7053be5794dd3233487..937a39034c73ebe5b5b717c3ade12c8f04498db9 100644
--- a/dev/tests/unit/testsuite/Magento/Install/App/Action/Plugin/DirTest.php
+++ b/dev/tests/unit/testsuite/Magento/Install/App/Action/Plugin/DirTest.php
@@ -78,7 +78,7 @@ class DirTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->varDirectory)
         );
         $logger = $this->getMock('Magento\Framework\Logger', array(), array(), '', false);
-        $this->subjectMock = $this->getMock('Magento\Install\Controller\Index', array(), array(), '', false);
+        $this->subjectMock = $this->getMock('Magento\Install\Controller\Index\Index', array(), array(), '', false);
         $this->requestMock = $this->getMock('Magento\Framework\App\RequestInterface');
         $this->plugin = new \Magento\Install\App\Action\Plugin\Dir($this->appStateMock, $filesystem, $logger);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Install/Controller/WizardTest.php b/dev/tests/unit/testsuite/Magento/Install/Controller/Wizard/LocaleTest.php
similarity index 97%
rename from dev/tests/unit/testsuite/Magento/Install/Controller/WizardTest.php
rename to dev/tests/unit/testsuite/Magento/Install/Controller/Wizard/LocaleTest.php
index f5799447448f6a99d1f4a38fc73809b5057b257d..f456fcc56f757d30dd3a59170e1863d7c81049ab 100644
--- a/dev/tests/unit/testsuite/Magento/Install/Controller/WizardTest.php
+++ b/dev/tests/unit/testsuite/Magento/Install/Controller/Wizard/LocaleTest.php
@@ -25,14 +25,14 @@
 /**
  * Test class for \Magento\Install\Block\Wizard
  */
-namespace Magento\Install\Controller;
+namespace Magento\Install\Controller\Wizard;
 
 /**
  * Class WizardTest
  *
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class WizardTest extends \PHPUnit_Framework_TestCase
+class LocaleTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * Locale to test
@@ -260,7 +260,7 @@ class WizardTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_controller = $this->_objectManager->getObject(
-            'Magento\Install\Controller\Wizard',
+            'Magento\Install\Controller\Wizard\Locale',
             array(
                 'context' => $this->_contextMock,
                 'configScope' => $this->_getClearMock('Magento\Framework\Config\Scope'),
@@ -289,9 +289,9 @@ class WizardTest extends \PHPUnit_Framework_TestCase
     /**
      * Test setting locale from session
      */
-    public function testLocaleAction()
+    public function testExecute()
     {
-        $this->_controller->localeAction();
+        $this->_controller->execute();
         $this->assertEquals(
             $this->_block->getLocaleCode(),
             self::LOCALE,
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/DeleteTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/DeleteTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..24ab0b5eafea4fb6322b57d55d518ab2554367f7
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/DeleteTest.php
@@ -0,0 +1,260 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+use Magento\Integration\Model\Integration as IntegrationModel;
+
+class DeleteTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testDeleteAction()
+    {
+        $intData = $this->_getSampleIntegrationData();
+        $this->_requestMock->expects(
+            $this->once()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'delete'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // verify success message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addSuccess'
+            )->with(
+                __('The integration \'%1\' has been deleted.', $intData[Info::DATA_NAME])
+            );
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+
+    public function testDeleteActionWithConsumer()
+    {
+        $intData = $this->_getSampleIntegrationData();
+        $intData[Info::DATA_CONSUMER_ID] = 1;
+        $this->_requestMock->expects(
+            $this->once()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->once()
+        )->method(
+                'delete'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_oauthSvcMock->expects(
+            $this->once()
+        )->method(
+                'deleteConsumer'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // verify success message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addSuccess'
+            )->with(
+                __('The integration \'%1\' has been deleted.', $intData[Info::DATA_NAME])
+            );
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+
+    public function testDeleteActionConfigSetUp()
+    {
+        $intData = $this->_getSampleIntegrationData();
+        $intData[Info::DATA_SETUP_TYPE] = IntegrationModel::TYPE_CONFIG;
+        $this->_requestMock->expects(
+            $this->once()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_integrationHelperMock->expects(
+            $this->once()
+        )->method(
+                'isConfigType'
+            )->with(
+                $intData
+            )->will(
+                $this->returnValue(true)
+            );
+        // verify error message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addError'
+            )->with(
+                __('Uninstall the extension to remove integration \'%1\'.', $intData[Info::DATA_NAME])
+            );
+        $this->_integrationSvcMock->expects($this->never())->method('delete');
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // verify success message
+        $this->_messageManager->expects($this->never())->method('addSuccess');
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+
+    public function testDeleteActionMissingId()
+    {
+        $this->_integrationSvcMock->expects($this->never())->method('get');
+        $this->_integrationSvcMock->expects($this->never())->method('delete');
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // verify error message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addError'
+            )->with(
+                __('Integration ID is not specified or is invalid.')
+            );
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+
+    public function testDeleteActionForServiceIntegrationException()
+    {
+        $intData = $this->_getSampleIntegrationData();
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_requestMock->expects(
+            $this->once()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        $exceptionMessage = __("Integration with ID '%1' doesn't exist.", $intData[Info::DATA_ID]);
+        $invalidIdException = new \Magento\Integration\Exception($exceptionMessage);
+        $this->_integrationSvcMock->expects(
+            $this->once()
+        )->method(
+                'delete'
+            )->will(
+                $this->throwException($invalidIdException)
+            );
+        $this->_messageManager->expects($this->once())->method('addError')->with($exceptionMessage);
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+
+    public function testDeleteActionForServiceGenericException()
+    {
+        $intData = $this->_getSampleIntegrationData();
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_requestMock->expects(
+            $this->once()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        $exceptionMessage = __("Integration with ID '%1' doesn't exist.", $intData[Info::DATA_ID]);
+        $invalidIdException = new \Exception($exceptionMessage);
+        $this->_integrationSvcMock->expects(
+            $this->once()
+        )->method(
+                'delete'
+            )->will(
+                $this->throwException($invalidIdException)
+            );
+        //Generic Exception(non-Service) should never add the message in session for user display
+        $this->_messageManager->expects($this->never())->method('addError');
+        $integrationContr = $this->_createIntegrationController('Delete');
+        $integrationContr->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/EditTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/EditTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..87b2b0ca793fa965dc1e21c5acefe0d198463b40
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/EditTest.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+
+class EditTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testEditAction()
+    {
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->equalTo(self::INTEGRATION_ID)
+            )->will(
+                $this->returnValue($this->_getSampleIntegrationData())
+            );
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getParam'
+            )->with(
+                $this->equalTo(\Magento\Integration\Controller\Adminhtml\Integration::PARAM_INTEGRATION_ID)
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+        // put data in session, the magic function getFormData is called so, must match __call method name
+        $this->_backendSessionMock->expects(
+            $this->any()
+        )->method(
+                '__call'
+            )->will(
+                $this->returnValueMap(
+                    array(
+                        array('setIntegrationData'),
+                        array(
+                            'getIntegrationData',
+                            array(Info::DATA_ID => self::INTEGRATION_ID, Info::DATA_NAME => 'testIntegration')
+                        )
+                    )
+                )
+            );
+        $this->_verifyLoadAndRenderLayout();
+        $controller = $this->_createIntegrationController('Edit');
+        $controller->execute();
+    }
+
+    public function testEditActionNonExistentIntegration()
+    {
+        $exceptionMessage = 'This integration no longer exists.';
+        // verify the error
+        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
+        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
+        // put data in session, the magic function getFormData is called so, must match __call method name
+        $this->_backendSessionMock->expects(
+            $this->any()
+        )->method(
+                '__call'
+            )->will(
+                $this->returnValue(array('name' => 'nonExistentInt'))
+            );
+
+        $invalidIdException = new \Magento\Integration\Exception($exceptionMessage);
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->will(
+                $this->throwException($invalidIdException)
+            );
+        $this->_verifyLoadAndRenderLayout();
+        $integrationContr = $this->_createIntegrationController('Edit');
+        $integrationContr->execute();
+    }
+
+    public function testEditActionNoDataAdd()
+    {
+        $exceptionMessage = 'Integration ID is not specified or is invalid.';
+        // verify the error
+        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
+        $this->_verifyLoadAndRenderLayout();
+        $integrationContr = $this->_createIntegrationController('Edit');
+        $integrationContr->execute();
+    }
+
+    public function testEditException()
+    {
+        $exceptionMessage = 'Integration ID is not specified or is invalid.';
+        // verify the error
+        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
+        $this->_controller = $this->_createIntegrationController('Edit');
+        $this->_controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/IndexTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/IndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..abf3a5916ec1a854c1d21534722c210d20117ae9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/IndexTest.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+
+class IndexTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testIndexAction()
+    {
+        $this->_verifyLoadAndRenderLayout();
+        // renderLayout
+        $this->_controller = $this->_createIntegrationController('Index');
+        $this->_controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/NewActionTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/NewActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3168ed81ab93a7ddff25001db472965e0e029b9f
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/NewActionTest.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+class NewActionTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testNewAction()
+    {
+        $this->_verifyLoadAndRenderLayout();
+        // verify the request is forwarded to 'edit' action
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'setActionName'
+            )->with(
+                'edit'
+            )->will(
+                $this->returnValue($this->_requestMock)
+            );
+        $integrationContr = $this->_createIntegrationController('NewAction');
+        $integrationContr->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialogTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialogTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0ad8739ed7fb4d974e7d6d0ac526c6af3897ccc
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/PermissionsDialogTest.php
@@ -0,0 +1,92 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Framework\View\Layout\Element as LayoutElement;
+
+class PermissionsDialogTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testPermissionsDialog()
+    {
+        $controller = $this->_createIntegrationController('PermissionsDialog');
+
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getParam'
+            )->with(
+                $this->equalTo(\Magento\Integration\Controller\Adminhtml\Integration::PARAM_INTEGRATION_ID)
+            )->will(
+                $this->returnValue(self::INTEGRATION_ID)
+            );
+
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->equalTo(self::INTEGRATION_ID)
+            )->will(
+                $this->returnValue($this->_getSampleIntegrationData())
+            );
+
+        // @codingStandardsIgnoreStart
+        $handle = <<<HANDLE
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+    <handle id="adminhtml_integration_activate_permissions_webapi">
+       <referenceBlock name="integration.activate.permissions.tabs">
+          <block class="Magento\Webapi\Block\Adminhtml\Integration\Activate\Permissions\Tab\Webapi" name="integration_activate_permissions_tabs_webapi" template="integration/activate/permissions/tab/webapi.phtml"/>
+          <action method="addTab">
+             <argument name="name" xsi:type="string">integration_activate_permissions_tabs_webapi</argument>
+             <argument name="block" xsi:type="string">integration_activate_permissions_tabs_webapi</argument>
+          </action>
+       </referenceBlock>
+    </handle>
+</layout>
+HANDLE;
+        // @codingStandardsIgnoreEnd
+
+        $layoutUpdates = new LayoutElement($handle);
+        $this->_registryMock->expects($this->any())->method('register');
+
+        $this->_layoutMergeMock->expects(
+            $this->once()
+        )->method(
+                'getFileLayoutUpdatesXml'
+            )->will(
+                $this->returnValue($layoutUpdates)
+            );
+
+        $this->_viewMock->expects(
+            $this->once()
+        )->method(
+                'loadLayout'
+            )->with(
+                $this->equalTo(array('adminhtml_integration_activate_permissions_webapi'))
+            );
+
+        $controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/SaveTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/SaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b88bc5c9ad3f995dc3e2767f2717171b34bb4ee5
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/SaveTest.php
@@ -0,0 +1,206 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
+use Magento\Integration\Model\Integration as IntegrationModel;
+
+class SaveTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testSaveAction()
+    {
+        // Use real translate model
+        $this->_translateModelMock = null;
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getPost'
+            )->will(
+                $this->returnValue(
+                    array(
+                        \Magento\Integration\Controller\Adminhtml\Integration::PARAM_INTEGRATION_ID
+                            => self::INTEGRATION_ID
+                    )
+                )
+            );
+        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
+        $intData = $this->_getSampleIntegrationData();
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                self::INTEGRATION_ID
+            )->will(
+                $this->returnValue($intData)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'update'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($intData)
+            );
+        // verify success message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addSuccess'
+            )->with(
+                __('The integration \'%1\' has been saved.', $intData[Info::DATA_NAME])
+            );
+        $integrationContr = $this->_createIntegrationController('Save');
+        $integrationContr->execute();
+    }
+
+    public function testSaveActionException()
+    {
+        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
+
+        // Have integration service throw an exception to test exception path
+        $exceptionMessage = 'Internal error. Check exception log for details.';
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                self::INTEGRATION_ID
+            )->will(
+                $this->throwException(new \Magento\Framework\Model\Exception($exceptionMessage))
+            );
+        // Verify error
+        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
+        $integrationContr = $this->_createIntegrationController('Save');
+        $integrationContr->execute();
+    }
+
+    public function testSaveActionIntegrationException()
+    {
+        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
+
+        // Have integration service throw an exception to test exception path
+        $exceptionMessage = 'Internal error. Check exception log for details.';
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                self::INTEGRATION_ID
+            )->will(
+                $this->throwException(new \Magento\Integration\Exception($exceptionMessage))
+            );
+        // Verify error
+        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
+        $integrationContr = $this->_createIntegrationController('Save');
+        $integrationContr->execute();
+    }
+
+    public function testSaveActionNew()
+    {
+        $integration = $this->_getSampleIntegrationData();
+        //No id when New Integration is Post-ed
+        $integration->unsetData(array(IntegrationModel::ID, 'id'));
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getPost'
+            )->will(
+                $this->returnValue($integration->getData())
+            );
+        $integration->setData('id', self::INTEGRATION_ID);
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'create'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->returnValue($integration)
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                self::INTEGRATION_ID
+            )->will(
+                $this->returnValue(null)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // verify success message
+        $this->_messageManager->expects(
+            $this->once()
+        )->method(
+                'addSuccess'
+            )->with(
+                __('The integration \'%1\' has been saved.', $integration->getName())
+            );
+        $integrationContr = $this->_createIntegrationController('Save');
+        $integrationContr->execute();
+    }
+
+    public function testSaveActionExceptionDuringServiceCreation()
+    {
+        $exceptionMessage = 'Service could not be saved.';
+        $integration = $this->_getSampleIntegrationData();
+        // No id when New Integration is Post-ed
+        $integration->unsetData(array(IntegrationModel::ID, 'id'));
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getPost'
+            )->will(
+                $this->returnValue($integration->getData())
+            );
+        $integration->setData('id', self::INTEGRATION_ID);
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'create'
+            )->with(
+                $this->anything()
+            )->will(
+                $this->throwException(new \Magento\Integration\Exception($exceptionMessage))
+            );
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                self::INTEGRATION_ID
+            )->will(
+                $this->returnValue(null)
+            );
+        // Use real translate model
+        $this->_translateModelMock = null;
+        // Verify success message
+        $this->_messageManager->expects($this->once())->method('addError')->with($exceptionMessage);
+        $integrationController = $this->_createIntegrationController('Save');
+        $integrationController->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/TokensDialogTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/TokensDialogTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac2641b635eec6b74bc08ec88374354df25b7db9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/Integration/TokensDialogTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Integration\Controller\Adminhtml\Integration;
+
+use Magento\Integration\Model\Integration as IntegrationModel;
+
+class TokensDialogTest extends \Magento\Integration\Controller\Adminhtml\IntegrationTest
+{
+    public function testTokensDialog()
+    {
+        $controller = $this->_createIntegrationController('TokensDialog');
+        $this->_registryMock->expects($this->any())->method('register');
+
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValueMap(
+                    array(
+                        array(
+                            \Magento\Integration\Controller\Adminhtml\Integration::PARAM_INTEGRATION_ID,
+                            null,
+                            self::INTEGRATION_ID),
+                        array(\Magento\Integration\Controller\Adminhtml\Integration::PARAM_REAUTHORIZE, 0, 0)
+                    )
+                )
+            );
+
+        $this->_integrationSvcMock->expects(
+            $this->any()
+        )->method(
+                'get'
+            )->with(
+                $this->equalTo(self::INTEGRATION_ID)
+            )->will(
+                $this->returnValue($this->_getIntegrationModelMock())
+            );
+
+        $this->_oauthSvcMock->expects($this->once())->method('createAccessToken')->will($this->returnValue(true));
+
+        $this->_viewMock->expects($this->any())->method('loadLayout');
+        $this->_viewMock->expects($this->any())->method('renderLayout');
+
+        $controller->execute();
+    }
+
+    public function testTokensExchangeReauthorize()
+    {
+        $controller = $this->_createIntegrationController('TokensExchange');
+
+        $this->_requestMock->expects(
+            $this->any()
+        )->method(
+                'getParam'
+            )->will(
+                $this->returnValueMap(
+                    array(
+                        array(
+                            \Magento\Integration\Controller\Adminhtml\Integration::PARAM_INTEGRATION_ID,
+                            null,
+                            self::INTEGRATION_ID
+                        ),
+                        array(\Magento\Integration\Controller\Adminhtml\Integration::PARAM_REAUTHORIZE, 0, 1)
+                    )
+                )
+            );
+
+        $this->_integrationSvcMock->expects(
+            $this->once()
+        )->method(
+                'get'
+            )->with(
+                $this->equalTo(self::INTEGRATION_ID)
+            )->will(
+                $this->returnValue($this->_getIntegrationModelMock())
+            );
+
+        $this->_oauthSvcMock->expects($this->once())->method('deleteToken');
+        $this->_oauthSvcMock->expects($this->once())->method('postToConsumer');
+
+        $this->_messageManager->expects($this->once())->method('addNotice');
+        $this->_messageManager->expects($this->never())->method('addError');
+        $this->_messageManager->expects($this->never())->method('addSuccess');
+
+        $this->_viewMock->expects($this->once())->method('loadLayout');
+        $this->_viewMock->expects($this->once())->method('renderLayout');
+
+        $this->_responseMock->expects($this->once())->method('getBody');
+        $this->_responseMock->expects($this->once())->method('representJson');
+
+        $controller->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
index 2f92bf8265bff637c55991b526f4ed538d300396..cd5778e03072b81ef2e8919ae3e5a8999790e12b 100644
--- a/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
+++ b/dev/tests/unit/testsuite/Magento/Integration/Controller/Adminhtml/IntegrationTest.php
@@ -27,13 +27,12 @@ namespace Magento\Integration\Controller\Adminhtml;
 
 use Magento\Integration\Block\Adminhtml\Integration\Edit\Tab\Info;
 use Magento\Integration\Model\Integration as IntegrationModel;
-use Magento\Framework\View\Layout\Element as LayoutElement;
 
 /**
  * @SuppressWarnings(PHPMD.TooManyFields)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class IntegrationTest extends \PHPUnit_Framework_TestCase
+abstract class IntegrationTest extends \PHPUnit_Framework_TestCase
 {
     /** @var \Magento\Integration\Controller\Adminhtml\Integration */
     protected $_controller;
@@ -160,665 +159,11 @@ class IntegrationTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->getMock();
     }
 
-    public function testIndexAction()
-    {
-        $this->_verifyLoadAndRenderLayout();
-        // renderLayout
-        $this->_controller = $this->_createIntegrationController();
-        $this->_controller->indexAction();
-    }
-
-    public function testNewAction()
-    {
-        $this->_verifyLoadAndRenderLayout();
-        // verify the request is forwarded to 'edit' action
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'setActionName'
-        )->with(
-            'edit'
-        )->will(
-            $this->returnValue($this->_requestMock)
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->newAction();
-    }
-
-    public function testEditAction()
-    {
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->equalTo(self::INTEGRATION_ID)
-        )->will(
-            $this->returnValue($this->_getSampleIntegrationData())
-        );
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getParam'
-        )->with(
-            $this->equalTo(Integration::PARAM_INTEGRATION_ID)
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        // put data in session, the magic function getFormData is called so, must match __call method name
-        $this->_backendSessionMock->expects(
-            $this->any()
-        )->method(
-            '__call'
-        )->will(
-            $this->returnValueMap(
-                array(
-                    array('setIntegrationData'),
-                    array(
-                        'getIntegrationData',
-                        array(Info::DATA_ID => self::INTEGRATION_ID, Info::DATA_NAME => 'testIntegration')
-                    )
-                )
-            )
-        );
-        $this->_verifyLoadAndRenderLayout();
-        $controller = $this->_createIntegrationController();
-        $controller->editAction();
-    }
-
-    public function testEditActionNonExistentIntegration()
-    {
-        $exceptionMessage = 'This integration no longer exists.';
-        // verify the error
-        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
-        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
-        // put data in session, the magic function getFormData is called so, must match __call method name
-        $this->_backendSessionMock->expects(
-            $this->any()
-        )->method(
-            '__call'
-        )->will(
-            $this->returnValue(array('name' => 'nonExistentInt'))
-        );
-
-        $invalidIdException = new \Magento\Integration\Exception($exceptionMessage);
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->will(
-            $this->throwException($invalidIdException)
-        );
-        $this->_verifyLoadAndRenderLayout();
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->editAction();
-    }
-
-    public function testEditActionNoDataAdd()
-    {
-        $exceptionMessage = 'Integration ID is not specified or is invalid.';
-        // verify the error
-        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
-        $this->_verifyLoadAndRenderLayout();
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->editAction();
-    }
-
-    public function testEditException()
-    {
-        $exceptionMessage = 'Integration ID is not specified or is invalid.';
-        // verify the error
-        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
-        $this->_controller = $this->_createIntegrationController();
-        $this->_controller->editAction();
-    }
-
-    public function testSaveAction()
-    {
-        // Use real translate model
-        $this->_translateModelMock = null;
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getPost'
-        )->will(
-            $this->returnValue(array(Integration::PARAM_INTEGRATION_ID => self::INTEGRATION_ID))
-        );
-        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
-        $intData = $this->_getSampleIntegrationData();
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            self::INTEGRATION_ID
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'update'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        // verify success message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addSuccess'
-        )->with(
-            __('The integration \'%1\' has been saved.', $intData[Info::DATA_NAME])
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->saveAction();
-    }
-
-    public function testSaveActionException()
-    {
-        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
-
-        // Have integration service throw an exception to test exception path
-        $exceptionMessage = 'Internal error. Check exception log for details.';
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            self::INTEGRATION_ID
-        )->will(
-            $this->throwException(new \Magento\Framework\Model\Exception($exceptionMessage))
-        );
-        // Verify error
-        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->saveAction();
-    }
-
-    public function testSaveActionIntegrationException()
-    {
-        $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(self::INTEGRATION_ID));
-
-        // Have integration service throw an exception to test exception path
-        $exceptionMessage = 'Internal error. Check exception log for details.';
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            self::INTEGRATION_ID
-        )->will(
-            $this->throwException(new \Magento\Integration\Exception($exceptionMessage))
-        );
-        // Verify error
-        $this->_messageManager->expects($this->once())->method('addError')->with($this->equalTo($exceptionMessage));
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->saveAction();
-    }
-
-    public function testSaveActionNew()
-    {
-        $integration = $this->_getSampleIntegrationData();
-        //No id when New Integration is Post-ed
-        $integration->unsetData(array(IntegrationModel::ID, 'id'));
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getPost'
-        )->will(
-            $this->returnValue($integration->getData())
-        );
-        $integration->setData('id', self::INTEGRATION_ID);
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'create'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($integration)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            self::INTEGRATION_ID
-        )->will(
-            $this->returnValue(null)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // verify success message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addSuccess'
-        )->with(
-            __('The integration \'%1\' has been saved.', $integration->getName())
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->saveAction();
-    }
-
-    public function testSaveActionExceptionDuringServiceCreation()
-    {
-        $exceptionMessage = 'Service could not be saved.';
-        $integration = $this->_getSampleIntegrationData();
-        // No id when New Integration is Post-ed
-        $integration->unsetData(array(IntegrationModel::ID, 'id'));
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getPost'
-        )->will(
-            $this->returnValue($integration->getData())
-        );
-        $integration->setData('id', self::INTEGRATION_ID);
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'create'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->throwException(new \Magento\Integration\Exception($exceptionMessage))
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            self::INTEGRATION_ID
-        )->will(
-            $this->returnValue(null)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // Verify success message
-        $this->_messageManager->expects($this->once())->method('addError')->with($exceptionMessage);
-        $integrationController = $this->_createIntegrationController();
-        $integrationController->saveAction();
-    }
-
-    public function testDeleteAction()
-    {
-        $intData = $this->_getSampleIntegrationData();
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'delete'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // verify success message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addSuccess'
-        )->with(
-            __('The integration \'%1\' has been deleted.', $intData[Info::DATA_NAME])
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testDeleteActionWithConsumer()
-    {
-        $intData = $this->_getSampleIntegrationData();
-        $intData[Info::DATA_CONSUMER_ID] = 1;
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->once()
-        )->method(
-            'delete'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_oauthSvcMock->expects(
-            $this->once()
-        )->method(
-            'deleteConsumer'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // verify success message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addSuccess'
-        )->with(
-            __('The integration \'%1\' has been deleted.', $intData[Info::DATA_NAME])
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testDeleteActionConfigSetUp()
-    {
-        $intData = $this->_getSampleIntegrationData();
-        $intData[Info::DATA_SETUP_TYPE] = IntegrationModel::TYPE_CONFIG;
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_integrationHelperMock->expects(
-            $this->once()
-        )->method(
-            'isConfigType'
-        )->with(
-            $intData
-        )->will(
-            $this->returnValue(true)
-        );
-        // verify error message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addError'
-        )->with(
-            __('Uninstall the extension to remove integration \'%1\'.', $intData[Info::DATA_NAME])
-        );
-        $this->_integrationSvcMock->expects($this->never())->method('delete');
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // verify success message
-        $this->_messageManager->expects($this->never())->method('addSuccess');
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testDeleteActionMissingId()
-    {
-        $this->_integrationSvcMock->expects($this->never())->method('get');
-        $this->_integrationSvcMock->expects($this->never())->method('delete');
-        // Use real translate model
-        $this->_translateModelMock = null;
-        // verify error message
-        $this->_messageManager->expects(
-            $this->once()
-        )->method(
-            'addError'
-        )->with(
-            __('Integration ID is not specified or is invalid.')
-        );
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testDeleteActionForServiceIntegrationException()
-    {
-        $intData = $this->_getSampleIntegrationData();
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        $exceptionMessage = __("Integration with ID '%1' doesn't exist.", $intData[Info::DATA_ID]);
-        $invalidIdException = new \Magento\Integration\Exception($exceptionMessage);
-        $this->_integrationSvcMock->expects(
-            $this->once()
-        )->method(
-            'delete'
-        )->will(
-            $this->throwException($invalidIdException)
-        );
-        $this->_messageManager->expects($this->once())->method('addError')->with($exceptionMessage);
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testDeleteActionForServiceGenericException()
-    {
-        $intData = $this->_getSampleIntegrationData();
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->anything()
-        )->will(
-            $this->returnValue($intData)
-        );
-        $this->_requestMock->expects(
-            $this->once()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-        // Use real translate model
-        $this->_translateModelMock = null;
-        $exceptionMessage = __("Integration with ID '%1' doesn't exist.", $intData[Info::DATA_ID]);
-        $invalidIdException = new \Exception($exceptionMessage);
-        $this->_integrationSvcMock->expects(
-            $this->once()
-        )->method(
-            'delete'
-        )->will(
-            $this->throwException($invalidIdException)
-        );
-        //Generic Exception(non-Service) should never add the message in session for user display
-        $this->_messageManager->expects($this->never())->method('addError');
-        $integrationContr = $this->_createIntegrationController();
-        $integrationContr->deleteAction();
-    }
-
-    public function testPermissionsDialog()
-    {
-        $controller = $this->_createIntegrationController();
-
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getParam'
-        )->with(
-            $this->equalTo(Integration::PARAM_INTEGRATION_ID)
-        )->will(
-            $this->returnValue(self::INTEGRATION_ID)
-        );
-
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->equalTo(self::INTEGRATION_ID)
-        )->will(
-            $this->returnValue($this->_getSampleIntegrationData())
-        );
-
-        // @codingStandardsIgnoreStart
-        $handle = <<<HANDLE
-<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
-    <handle id="adminhtml_integration_activate_permissions_webapi">
-       <referenceBlock name="integration.activate.permissions.tabs">
-          <block class="Magento\Webapi\Block\Adminhtml\Integration\Activate\Permissions\Tab\Webapi" name="integration_activate_permissions_tabs_webapi" template="integration/activate/permissions/tab/webapi.phtml"/>
-          <action method="addTab">
-             <argument name="name" xsi:type="string">integration_activate_permissions_tabs_webapi</argument>
-             <argument name="block" xsi:type="string">integration_activate_permissions_tabs_webapi</argument>
-          </action>
-       </referenceBlock>
-    </handle>
-</layout>
-HANDLE;
-        // @codingStandardsIgnoreEnd
-
-        $layoutUpdates = new LayoutElement($handle);
-        $this->_registryMock->expects($this->any())->method('register');
-
-        $this->_layoutMergeMock->expects(
-            $this->once()
-        )->method(
-            'getFileLayoutUpdatesXml'
-        )->will(
-            $this->returnValue($layoutUpdates)
-        );
-
-        $this->_viewMock->expects(
-            $this->once()
-        )->method(
-            'loadLayout'
-        )->with(
-            $this->equalTo(array('adminhtml_integration_activate_permissions_webapi'))
-        );
-
-        $controller->permissionsDialogAction();
-    }
-
-    public function testTokensDialog()
-    {
-        $controller = $this->_createIntegrationController();
-        $this->_registryMock->expects($this->any())->method('register');
-
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValueMap(
-                array(
-                    array(Integration::PARAM_INTEGRATION_ID, null, self::INTEGRATION_ID),
-                    array(Integration::PARAM_REAUTHORIZE, 0, 0)
-                )
-            )
-        );
-
-        $this->_integrationSvcMock->expects(
-            $this->any()
-        )->method(
-            'get'
-        )->with(
-            $this->equalTo(self::INTEGRATION_ID)
-        )->will(
-            $this->returnValue($this->_getIntegrationModelMock())
-        );
-
-        $this->_oauthSvcMock->expects($this->once())->method('createAccessToken')->will($this->returnValue(true));
-
-        $this->_viewMock->expects($this->any())->method('loadLayout');
-        $this->_viewMock->expects($this->any())->method('renderLayout');
-
-        $controller->tokensDialogAction();
-    }
-
-    public function testTokensExchangeReauthorize()
-    {
-        $controller = $this->_createIntegrationController();
-
-        $this->_requestMock->expects(
-            $this->any()
-        )->method(
-            'getParam'
-        )->will(
-            $this->returnValueMap(
-                array(
-                    array(Integration::PARAM_INTEGRATION_ID, null, self::INTEGRATION_ID),
-                    array(Integration::PARAM_REAUTHORIZE, 0, 1)
-                )
-            )
-        );
-
-        $this->_integrationSvcMock->expects(
-            $this->once()
-        )->method(
-            'get'
-        )->with(
-            $this->equalTo(self::INTEGRATION_ID)
-        )->will(
-            $this->returnValue($this->_getIntegrationModelMock())
-        );
-
-        $this->_oauthSvcMock->expects($this->once())->method('deleteToken');
-        $this->_oauthSvcMock->expects($this->once())->method('postToConsumer');
-
-        $this->_messageManager->expects($this->once())->method('addNotice');
-        $this->_messageManager->expects($this->never())->method('addError');
-        $this->_messageManager->expects($this->never())->method('addSuccess');
-
-        $this->_viewMock->expects($this->once())->method('loadLayout');
-        $this->_viewMock->expects($this->once())->method('renderLayout');
-
-        $this->_responseMock->expects($this->once())->method('getBody');
-        $this->_responseMock->expects($this->once())->method('representJson');
-
-        $controller->tokensExchangeAction();
-    }
-
     /**
-     * Creates the IntegrationController to test.
-     *
+     * @param string $actionName
      * @return \Magento\Integration\Controller\Adminhtml\Integration
      */
-    protected function _createIntegrationController()
+    protected function _createIntegrationController($actionName)
     {
         // Mock Layout passed into constructor
         $this->_viewMock = $this->getMock('Magento\Framework\App\ViewInterface');
@@ -838,7 +183,11 @@ HANDLE;
         // for _setActiveMenu
         $this->_viewMock->expects($this->any())->method('getLayout')->will($this->returnValue($this->_layoutMock));
         $blockMock = $this->getMockBuilder('Magento\Backend\Block\Menu')->disableOriginalConstructor()->getMock();
-        $menuMock = $this->getMockBuilder('Magento\Backend\Model\Menu')->disableOriginalConstructor()->getMock();
+        $menuMock = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
         $loggerMock = $this->getMockBuilder('Magento\Framework\Logger')->disableOriginalConstructor()->getMock();
         $loggerMock->expects($this->any())->method('logException')->will($this->returnSelf());
         $menuMock->expects($this->any())->method('getParentItems')->will($this->returnValue(array()));
@@ -885,7 +234,7 @@ HANDLE;
         );
         /** Create IntegrationController to test */
         $controller = $this->_objectManagerHelper->getObject(
-            'Magento\Integration\Controller\Adminhtml\Integration',
+            '\\Magento\\Integration\\Controller\\Adminhtml\\Integration\\' . $actionName,
             $subControllerParams
         );
         return $controller;
diff --git a/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/PluginTest.php b/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/PluginTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bd1b5ec2750b993d887abf8b5dd758c0632bae9e
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Multishipping/Controller/Checkout/PluginTest.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Multishipping\Controller\Checkout;
+
+class PluginTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $cartMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteMock;
+
+    /**
+     * @var Plugin
+     */
+    protected $object;
+
+    protected function setUp()
+    {
+        $this->cartMock = $this->getMock('Magento\Checkout\Model\Cart', [], [], '', false);
+        $this->quoteMock = $this->getMock(
+            'Magento\Sales\Model\Quote',
+            ['__wakeUp', 'setIsMultiShipping'],
+            [],
+            '',
+            false
+        );
+        $this->cartMock->expects($this->once())->method('getQuote')->will($this->returnValue($this->quoteMock));
+        $this->object = new Plugin($this->cartMock);
+    }
+
+    public function testExecuteTurnsOffMultishippingModeOnQuote()
+    {
+        $subject = $this->getMock('Magento\Checkout\Controller\Onepage\Index', [], [], '', false);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(0);
+        $this->object->beforeExecute($subject);
+    }
+} 
diff --git a/dev/tests/unit/testsuite/Magento/Newsletter/Controller/ManageTest.php b/dev/tests/unit/testsuite/Magento/Newsletter/Controller/Manage/SaveTest.php
similarity index 95%
rename from dev/tests/unit/testsuite/Magento/Newsletter/Controller/ManageTest.php
rename to dev/tests/unit/testsuite/Magento/Newsletter/Controller/Manage/SaveTest.php
index 8570345355054b223aeff1bd467371c1ee961ff5..a216c431cb50db080729a669fc183a5dbb57f984 100644
--- a/dev/tests/unit/testsuite/Magento/Newsletter/Controller/ManageTest.php
+++ b/dev/tests/unit/testsuite/Magento/Newsletter/Controller/Manage/SaveTest.php
@@ -21,19 +21,19 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Newsletter\Controller;
+namespace Magento\Newsletter\Controller\Manage;
 
 use Magento\Framework\Exception\NoSuchEntityException;
 
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class ManageTest extends \PHPUnit_Framework_TestCase
+class SaveTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Newsletter\Controller\Manage
      */
-    private $controller;
+    private $action;
 
     /**
      * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
@@ -99,7 +99,7 @@ class ManageTest extends \PHPUnit_Framework_TestCase
                 ->getMock();
         $objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
 
-        $this->controller = $objectManager->getObject('Magento\Newsletter\Controller\Manage', [
+        $this->action = $objectManager->getObject('Magento\Newsletter\Controller\Manage\Save', [
                 'request' => $this->requestMock,
                 'response' => $this->responseMock,
                 'messageManager' => $this->messageManagerMock,
@@ -122,7 +122,7 @@ class ManageTest extends \PHPUnit_Framework_TestCase
             ->method('addSuccess');
         $this->messageManagerMock->expects($this->never())
             ->method('addError');
-        $this->controller->saveAction();
+        $this->action->execute();
     }
 
     public function testSaveActionNoCustomerInSession()
@@ -141,7 +141,7 @@ class ManageTest extends \PHPUnit_Framework_TestCase
         $this->messageManagerMock->expects($this->once())
             ->method('addError')
             ->with('Something went wrong while saving your subscription.');
-        $this->controller->saveAction();
+        $this->action->execute();
     }
 
     public function testSaveActionWithException()
@@ -169,6 +169,6 @@ class ManageTest extends \PHPUnit_Framework_TestCase
         $this->messageManagerMock->expects($this->once())
             ->method('addError')
             ->with('Something went wrong while saving your subscription.');
-        $this->controller->saveAction();
+        $this->action->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCacheTest.php b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfigTest.php
similarity index 91%
rename from dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCacheTest.php
rename to dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfigTest.php
index e18bec3cbaf329d6e74b7042558d4f9c86fb9cba..edf8939a6de56680ddb88a6e7c72a33644e683ae 100644
--- a/dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCacheTest.php
+++ b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Adminhtml/PageCache/ExportVarnishConfigTest.php
@@ -25,13 +25,13 @@
 /**
  * Test class for \Magento\PageCache\Controller\Adminhtml/PageCache
  */
-namespace Magento\PageCache\Controller\Adminhtml;
+namespace Magento\PageCache\Controller\Adminhtml\PageCache;
 
 /**
  * Class PageCacheTest
  *
  */
-class PageCacheTest extends \PHPUnit_Framework_TestCase
+class ExportVarnishConfigTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
@@ -49,9 +49,9 @@ class PageCacheTest extends \PHPUnit_Framework_TestCase
     protected $viewMock;
 
     /**
-     * @var \Magento\PageCache\Controller\Adminhtml\PageCache
+     * @var \Magento\PageCache\Controller\Adminhtml\PageCache\ExportVarhishConfig
      */
-    protected $controller;
+    protected $action;
 
     /**
      * @var \Magento\Framework\App\Response\Http\FileFactory|\PHPUnit_Framework_MockObject_MockObject
@@ -90,7 +90,7 @@ class PageCacheTest extends \PHPUnit_Framework_TestCase
         $contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->responseMock));
         $contextMock->expects($this->any())->method('getView')->will($this->returnValue($this->viewMock));
 
-        $this->controller = new \Magento\PageCache\Controller\Adminhtml\PageCache(
+        $this->action = new \Magento\PageCache\Controller\Adminhtml\PageCache\ExportVarnishConfig(
             $contextMock,
             $this->fileFactoryMock,
             $this->configMock
@@ -118,7 +118,7 @@ class PageCacheTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($responseMock)
         );
 
-        $result = $this->controller->exportVarnishConfigAction();
+        $result = $this->action->execute();
         $this->assertInstanceOf('Magento\Framework\App\ResponseInterface', $result);
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/EsiTest.php b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/EsiTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ab2be5eae12748d63b99a24abdf2040340036be0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/EsiTest.php
@@ -0,0 +1,157 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\PageCache\Controller\Block;
+
+class EsiTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\App\Response\Http|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    /**
+     * @var \Magento\Framework\App\View|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $viewMock;
+
+    /**
+     * @var \Magento\PageCache\Controller\Block
+     */
+    protected $action;
+
+    /**
+     * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $layoutMock;
+
+    /**
+     * Set up before test
+     */
+    protected function setUp()
+    {
+        $this->layoutMock = $this->getMockBuilder(
+            'Magento\Framework\View\Layout'
+        )->disableOriginalConstructor()->getMock();
+
+        $contextMock =
+            $this->getMockBuilder('Magento\Framework\App\Action\Context')->disableOriginalConstructor()->getMock();
+
+        $this->requestMock = $this->getMockBuilder(
+            'Magento\Framework\App\Request\Http'
+        )->disableOriginalConstructor()->getMock();
+        $this->responseMock = $this->getMockBuilder(
+            'Magento\Framework\App\Response\Http'
+        )->disableOriginalConstructor()->getMock();
+        $this->viewMock = $this->getMockBuilder('Magento\Framework\App\View')->disableOriginalConstructor()->getMock();
+
+        $contextMock->expects($this->any())->method('getRequest')->will($this->returnValue($this->requestMock));
+        $contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->responseMock));
+        $contextMock->expects($this->any())->method('getView')->will($this->returnValue($this->viewMock));
+
+        $this->action = new \Magento\PageCache\Controller\Block\Esi($contextMock);
+    }
+
+    /**
+     * @dataProvider executeDataProvider
+     * @param string $blockClass
+     * @param bool $shouldSetHeaders
+     */
+    public function testExecute($blockClass, $shouldSetHeaders)
+    {
+        $block = 'block';
+        $handles = array('handle1', 'handle2');
+        $html = 'some-html';
+        $mapData = array(array('blocks', '', json_encode(array($block))), array('handles', '', json_encode($handles)));
+
+        $blockInstance1 = $this->getMock(
+            $blockClass,
+            array('toHtml'),
+            array(),
+            '',
+            false
+        );
+
+        $blockInstance1->expects($this->once())->method('toHtml')->will($this->returnValue($html));
+        $blockInstance1->setTtl(360);
+
+        $this->requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap($mapData));
+
+        $this->viewMock->expects($this->once())->method('loadLayout')->with($this->equalTo($handles));
+
+        $this->viewMock->expects($this->once())->method('getLayout')->will($this->returnValue($this->layoutMock));
+
+        $this->layoutMock->expects(
+            $this->once()
+        )->method(
+                'getBlock'
+            )->with(
+                $this->equalTo($block)
+            )->will(
+                $this->returnValue($blockInstance1)
+            );
+
+        if ($shouldSetHeaders) {
+            $this->responseMock->expects($this->once())
+                ->method('setHeader')
+                ->with('X-Magento-Tags', implode(',', $blockInstance1->getIdentities()));
+        } else {
+            $this->responseMock->expects($this->never())
+                ->method('setHeader');
+        }
+
+        $this->responseMock->expects($this->once())
+            ->method('appendBody')
+            ->with($this->equalTo($html));
+
+        $this->action->execute();
+    }
+
+    public function executeDataProvider()
+    {
+        return array(
+            array('Magento\PageCache\Block\Controller\StubBlock', true),
+            array('Magento\Framework\View\Element\AbstractBlock', false),
+        );
+    }
+
+    public function testExecuteBlockNotExists()
+    {
+        $handles = json_encode(array('handle1', 'handle2'));
+        $mapData = array(
+            array('blocks', '', null),
+            array('handles', '', $handles)
+        );
+
+        $this->requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap($mapData));
+        $this->viewMock->expects($this->never())->method('getLayout')->will($this->returnValue($this->layoutMock));
+
+        $this->action->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/PageCache/Controller/BlockTest.php b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/RenderTest.php
similarity index 57%
rename from dev/tests/unit/testsuite/Magento/PageCache/Controller/BlockTest.php
rename to dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/RenderTest.php
index 8c52adff42d7657097e0d9153b6fc2e30e25fee7..d01e500f272d4f1c2cd1bbcbb8183da04c7b3c13 100644
--- a/dev/tests/unit/testsuite/Magento/PageCache/Controller/BlockTest.php
+++ b/dev/tests/unit/testsuite/Magento/PageCache/Controller/Block/RenderTest.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -22,16 +23,10 @@
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-/**
- * Test class for \Magento\PageCache\Controller\Block
- */
-namespace Magento\PageCache\Controller;
+namespace Magento\PageCache\Controller\Block;
 
-/**
- * Class BlockTest
- *
- */
-class BlockTest extends \PHPUnit_Framework_TestCase
+
+class RenderTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Framework\App\Request\Http|\PHPUnit_Framework_MockObject_MockObject
@@ -51,7 +46,7 @@ class BlockTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\PageCache\Controller\Block
      */
-    protected $controller;
+    protected $action;
 
     /**
      * @var \Magento\Framework\View\Layout|\PHPUnit_Framework_MockObject_MockObject
@@ -82,21 +77,21 @@ class BlockTest extends \PHPUnit_Framework_TestCase
         $contextMock->expects($this->any())->method('getResponse')->will($this->returnValue($this->responseMock));
         $contextMock->expects($this->any())->method('getView')->will($this->returnValue($this->viewMock));
 
-        $this->controller = new \Magento\PageCache\Controller\Block($contextMock);
+        $this->action = new \Magento\PageCache\Controller\Block\Render($contextMock);
     }
 
-    public function testRenderActionNotAjax()
+    public function testExecuteNotAjax()
     {
         $this->requestMock->expects($this->once())->method('isAjax')->will($this->returnValue(false));
         $this->requestMock->expects($this->once())->method('setActionName')->will($this->returnValue('noroute'));
         $this->requestMock->expects($this->once())->method('setDispatched')->will($this->returnValue(false));
-        $this->controller->renderAction();
+        $this->action->execute();
     }
 
     /**
      * Test no params: blocks, handles
      */
-    public function testRenderActionNoParams()
+    public function testExecuteNoParams()
     {
         $this->requestMock->expects($this->once())->method('isAjax')->will($this->returnValue(true));
         $this->requestMock->expects($this->at(1))
@@ -107,10 +102,10 @@ class BlockTest extends \PHPUnit_Framework_TestCase
             ->method('getParam')
             ->with($this->equalTo('handles'), $this->equalTo(''))
             ->will($this->returnValue(''));
-        $this->controller->renderAction();
+        $this->action->execute();
     }
 
-    public function testRenderAction()
+    public function testExecute()
     {
         $blocks = array('block1', 'block2');
         $handles = array('handle1', 'handle2');
@@ -138,129 +133,52 @@ class BlockTest extends \PHPUnit_Framework_TestCase
         $this->requestMock->expects(
             $this->at(1)
         )->method(
-            'getParam'
-        )->with(
-            $this->equalTo('blocks'),
-            $this->equalTo('')
-        )->will(
-            $this->returnValue(json_encode($blocks))
-        );
+                'getParam'
+            )->with(
+                $this->equalTo('blocks'),
+                $this->equalTo('')
+            )->will(
+                $this->returnValue(json_encode($blocks))
+            );
         $this->requestMock->expects(
             $this->at(2)
         )->method(
-            'getParam'
-        )->with(
-            $this->equalTo('handles'),
-            $this->equalTo('')
-        )->will(
-            $this->returnValue(json_encode($handles))
-        );
+                'getParam'
+            )->with(
+                $this->equalTo('handles'),
+                $this->equalTo('')
+            )->will(
+                $this->returnValue(json_encode($handles))
+            );
         $this->viewMock->expects($this->once())->method('loadLayout')->with($this->equalTo($handles));
         $this->viewMock->expects($this->any())->method('getLayout')->will($this->returnValue($this->layoutMock));
         $this->layoutMock->expects(
             $this->at(0)
         )->method(
-            'getBlock'
-        )->with(
-            $this->equalTo($blocks[0])
-        )->will(
-            $this->returnValue($blockInstance1)
-        );
+                'getBlock'
+            )->with(
+                $this->equalTo($blocks[0])
+            )->will(
+                $this->returnValue($blockInstance1)
+            );
         $this->layoutMock->expects(
             $this->at(1)
         )->method(
-            'getBlock'
-        )->with(
-            $this->equalTo($blocks[1])
-        )->will(
-            $this->returnValue($blockInstance2)
-        );
+                'getBlock'
+            )->with(
+                $this->equalTo($blocks[1])
+            )->will(
+                $this->returnValue($blockInstance2)
+            );
 
         $this->responseMock->expects(
             $this->once()
         )->method(
-            'appendBody'
-        )->with(
-            $this->equalTo(json_encode($expectedData))
-        );
-
-        $this->controller->renderAction();
-    }
-
-    /**
-     * @dataProvider esiActionDataProvider
-     * @param string $blockClass
-     * @param bool $shouldSetHeaders
-     */
-    public function testEsiAction($blockClass, $shouldSetHeaders)
-    {
-        $block = 'block';
-        $handles = array('handle1', 'handle2');
-        $html = 'some-html';
-        $mapData = array(array('blocks', '', json_encode(array($block))), array('handles', '', json_encode($handles)));
-
-        $blockInstance1 = $this->getMock(
-            $blockClass,
-            array('toHtml'),
-            array(),
-            '',
-            false
-        );
-
-        $blockInstance1->expects($this->once())->method('toHtml')->will($this->returnValue($html));
-        $blockInstance1->setTtl(360);
-
-        $this->requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap($mapData));
-
-        $this->viewMock->expects($this->once())->method('loadLayout')->with($this->equalTo($handles));
-
-        $this->viewMock->expects($this->once())->method('getLayout')->will($this->returnValue($this->layoutMock));
-
-        $this->layoutMock->expects(
-            $this->once()
-        )->method(
-            'getBlock'
-        )->with(
-            $this->equalTo($block)
-        )->will(
-            $this->returnValue($blockInstance1)
-        );
-
-        if ($shouldSetHeaders) {
-            $this->responseMock->expects($this->once())
-                ->method('setHeader')
-                ->with('X-Magento-Tags', implode(',', $blockInstance1->getIdentities()));
-        } else {
-            $this->responseMock->expects($this->never())
-                ->method('setHeader');
-        }
-
-        $this->responseMock->expects($this->once())
-            ->method('appendBody')
-            ->with($this->equalTo($html));
-
-        $this->controller->esiAction();
-    }
-
-    public function esiActionDataProvider()
-    {
-        return array(
-            array('Magento\PageCache\Block\Controller\StubBlock', true),
-            array('Magento\Framework\View\Element\AbstractBlock', false),
-        );
-    }
-
-    public function testEsiActionBlockNotExists()
-    {
-        $handles = json_encode(array('handle1', 'handle2'));
-        $mapData = array(
-            array('blocks', '', null),
-            array('handles', '', $handles)
-        );
-
-        $this->requestMock->expects($this->any())->method('getParam')->will($this->returnValueMap($mapData));
-        $this->viewMock->expects($this->never())->method('getLayout')->will($this->returnValue($this->layoutMock));
+                'appendBody'
+            )->with(
+                $this->equalTo(json_encode($expectedData))
+            );
 
-        $this->controller->esiAction();
+        $this->action->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/PageCache/Model/ObserverTest.php b/dev/tests/unit/testsuite/Magento/PageCache/Model/ObserverTest.php
index 02faf8ab2081bc4d48d88cdeb4a4ccce09ef2ab5..369230ae419a45d053e6ccbd6d47e140ae9471ac 100644
--- a/dev/tests/unit/testsuite/Magento/PageCache/Model/ObserverTest.php
+++ b/dev/tests/unit/testsuite/Magento/PageCache/Model/ObserverTest.php
@@ -61,6 +61,9 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
     /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Session\Generic */
     protected $_session;
 
+    /** @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Framework\Escaper */
+    protected $_escaper;
+
     /**
      * Set up all mocks and data for test
      */
@@ -78,6 +81,7 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         $this->_typeListMock = $this->getMock('Magento\Framework\App\Cache\TypeList', array(), array(), '', false);
         $this->_formKey = $this->getMock('Magento\Framework\App\PageCache\FormKey', array(), array(), '', false);
         $this->_session = $this->getMock('Magento\Framework\Session\Generic', array('setData'), array(), '', false);
+        $this->_escaper = $this->getMock('\Magento\Framework\Escaper', array('escapeHtml'), array(), '', false);
 
         $this->_model = new \Magento\PageCache\Model\Observer(
             $this->_configMock,
@@ -85,7 +89,8 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
             $this->_helperMock,
             $this->_typeListMock,
             $this->_formKey,
-            $this->_session
+            $this->_session,
+            $this->_escaper
         );
         $this->_observerMock = $this->getMock(
             'Magento\Framework\Event\Observer',
@@ -313,18 +318,22 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
     public function testRegisterFormKeyFromCookie()
     {
         //Data
-        $formKey = 'asdfaswqrwqe12';
+        $formKey = '<asdfaswqrwqe12>';
+        $escapedFormKey = 'asdfaswqrwqe12';
 
         //Verification
-        $this->_formKey->expects($this->once())->method('get')->will($this->returnValue($formKey));
-        $this->_session->expects(
-            $this->once()
-        )->method(
-            'setData'
-        )->with(
-            \Magento\Framework\Data\Form\FormKey::FORM_KEY,
-            $formKey
-        );
+        $this->_formKey->expects($this->once())
+            ->method('get')
+            ->will($this->returnValue($formKey));
+
+        $this->_escaper->expects($this->once())
+            ->method('escapeHtml')
+            ->with($formKey)
+            ->will($this->returnValue($escapedFormKey));
+
+        $this->_session->expects($this->once())
+            ->method('setData')
+            ->with(\Magento\Framework\Data\Form\FormKey::FORM_KEY, $escapedFormKey);
 
         $this->_model->registerFormKeyFromCookie($this->_observerMock);
     }
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/Agreement/CancelTest.php
similarity index 92%
rename from dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php
rename to dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/Agreement/CancelTest.php
index 54273aa53f7bfad8ca0c68a65bf67a52d71c68f3..7ecb0a4e779a7c11dc9feff555213cffd863ee44 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/AgreementTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Billing/Agreement/CancelTest.php
@@ -21,9 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Paypal\Controller\Billing;
+namespace Magento\Paypal\Controller\Billing\Agreement;
 
-class AgreementTest extends \PHPUnit_Framework_TestCase
+class CancelTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Paypal\Controller\Billing\Agreement
@@ -113,10 +113,10 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
 
         $title = $this->getMock('Magento\Framework\App\Action\Title', array(), array(), '', false);
 
-        $this->_controller = new Agreement($context, $this->_registry, $title);
+        $this->_controller = new Cancel($context, $this->_registry, $title);
     }
 
-    public function testCancelActionSuccess()
+    public function testExecuteActionSuccess()
     {
         $this->_agreement->expects($this->once())->method('getReferenceId')->will($this->returnValue('r15'));
         $this->_agreement->expects($this->once())->method('canCancel')->will($this->returnValue(true));
@@ -136,10 +136,10 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
             $this->identicalTo($this->_agreement)
         );
 
-        $this->_controller->cancelAction();
+        $this->_controller->execute();
     }
 
-    public function testCancelActionAgreementDoesNotBelongToCustomer()
+    public function testExecuteAgreementDoesNotBelongToCustomer()
     {
         $this->_agreement->expects($this->never())->method('canCancel');
         $this->_agreement->expects($this->never())->method('cancel');
@@ -150,10 +150,10 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
 
         $this->_registry->expects($this->never())->method('register');
 
-        $this->_controller->cancelAction();
+        $this->_controller->execute();
     }
 
-    public function testCancelActionAgreementStatusDoesNotAllowToCancel()
+    public function testExecuteAgreementStatusDoesNotAllowToCancel()
     {
         $this->_agreement->expects($this->once())->method('canCancel')->will($this->returnValue(false));
         $this->_agreement->expects($this->never())->method('cancel');
@@ -171,6 +171,6 @@ class AgreementTest extends \PHPUnit_Framework_TestCase
             $this->identicalTo($this->_agreement)
         );
 
-        $this->_controller->cancelAction();
+        $this->_controller->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/PlaceOrderTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/PlaceOrderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e148d9cd4dc7bdb70af2cb5cfd12d689a896c48
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/PlaceOrderTest.php
@@ -0,0 +1,174 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class PlaceOrderTest extends \Magento\Paypal\Controller\ExpressTest
+{
+    protected $name = 'PlaceOrder';
+
+
+    /**
+     * @param bool $isGeneral
+     * @dataProvider trueFalseDataProvider
+     */
+    public function testExecuteNonProcessableException($isGeneral)
+    {
+        if (!$isGeneral) {
+            $this->request->expects($this->once())
+                ->method('getPost')
+                ->with('agreement', [])
+                ->will($this->returnValue([]));
+        }
+        $this->_expectRedirect();
+        $this->model->execute();
+    }
+
+    /**
+     * @param string $path
+     */
+    protected function _expectRedirect($path = '*/*/review')
+    {
+        $this->redirect->expects($this->once())
+            ->method('redirect')
+            ->with($this->anything(), $path, []);
+    }
+
+    public function trueFalseDataProvider()
+    {
+        return [[true], [false]];
+    }
+
+    /**
+     * @param int $code
+     * @param null|string $paymentAction
+     * @dataProvider executeProcessableExceptionDataProvider
+     */
+    public function testExecuteProcessableException($code, $paymentAction = null)
+    {
+        $this->request->expects($this->once())
+            ->method('getPost')
+            ->with('agreement', [])
+            ->will($this->returnValue([]));
+        $oldCallback = &$this->objectManagerCallback;
+        $this->objectManagerCallback = function ($className) use ($code, $oldCallback) {
+            $instance = call_user_func($oldCallback, $className);
+            if ($className == 'Magento\Checkout\Model\Agreements\AgreementsValidator') {
+                $exception = $this->getMock(
+                    'Magento\Paypal\Model\Api\ProcessableException',
+                    ['getUserMessage'],
+                    ['message', $code]
+                );
+                $exception->expects($this->any())
+                    ->method('getUserMessage')
+                    ->will($this->returnValue('User Message'));
+                $instance->expects($this->once())
+                    ->method('isValid')
+                    ->will($this->throwException($exception));
+            }
+            return $instance;
+        };
+        if (isset($paymentAction)) {
+            $this->config->expects($this->once())
+                ->method('getPaymentAction')
+                ->will($this->returnValue($paymentAction));
+        }
+        $this->_expectErrorCodes($code, $paymentAction);
+        $this->model->execute();
+    }
+
+    public function executeProcessableExceptionDataProvider()
+    {
+        return [
+            [\Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED],
+            [\Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED],
+            [\Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL],
+            [
+                \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE,
+                \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
+            ],
+            [\Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE, 'other'],
+            [999999],
+        ];
+    }
+
+    /**
+     * @param int $code
+     * @param null|string $paymentAction
+     */
+    protected function _expectErrorCodes($code, $paymentAction)
+    {
+        $redirectUrl = 'redirect by test';
+        if (in_array(
+            $code,
+            [
+                \Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED,
+                \Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED,
+            ]
+        )
+        ) {
+            $payment = new \Magento\Framework\Object(['checkout_redirect_url' => $redirectUrl]);
+            $this->quote->expects($this->once())
+                ->method('getPayment')
+                ->will($this->returnValue($payment));
+        }
+        if ($code == \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE
+            && $paymentAction == \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
+        ) {
+            $this->config->expects($this->once())
+                ->method('getExpressCheckoutOrderUrl')
+                ->will($this->returnValue($redirectUrl));
+        }
+        if ($code == \Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL
+            || $code == \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE
+            && $paymentAction != \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
+        ) {
+            $this->config->expects($this->once())
+                ->method('getExpressCheckoutStartUrl')
+                ->will($this->returnValue($redirectUrl));
+            $this->request->expects($this->once())
+                ->method('getParam')
+                ->with('token');
+        }
+        if (in_array(
+            $code,
+            [
+                \Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED,
+                \Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED,
+                \Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL,
+                \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE,
+            ]
+        )
+        ) {
+            $this->response->expects($this->once())
+                ->method('setRedirect')
+                ->with($redirectUrl);
+        } else {
+            $this->messageManager->expects($this->once())
+                ->method('addError')
+                ->with('User Message');
+            $this->_expectRedirect('checkout/cart');
+        }
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/ReturnActionTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/ReturnActionTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fea7d64845f5fcde6cd1337445c1212789e5583
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/ReturnActionTest.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class ReturnActionTest extends \Magento\Paypal\Controller\ExpressTest
+{
+    protected $name = 'ReturnAction';
+
+    /**
+     * @param string $path
+     */
+    protected function _expectRedirect($path = '*/*/review')
+    {
+        $this->redirect->expects($this->once())
+            ->method('redirect')
+            ->with($this->anything(), $path, []);
+    }
+
+    public function testExecuteAuthorizationRetrial()
+    {
+        $this->request->expects($this->once())
+            ->method('getParam')
+            ->with('retry_authorization')
+            ->will($this->returnValue('true'));
+        $this->checkoutSession->expects($this->once())
+            ->method('__call')
+            ->with('getPaypalTransactionData')
+            ->will($this->returnValue(['any array']));
+        $this->_expectForwardPlaceOrder();
+        $this->model->execute();
+    }
+
+    public function trueFalseDataProvider()
+    {
+        return [[true], [false]];
+    }
+
+    /**
+     * @param bool $canSkipOrderReviewStep
+     * @dataProvider trueFalseDataProvider
+     */
+    public function testExecute($canSkipOrderReviewStep)
+    {
+        $this->checkoutSession->expects($this->at(0))
+            ->method('__call')
+            ->with('unsPaypalTransactionData');
+        $this->checkout->expects($this->once())
+            ->method('canSkipOrderReviewStep')
+            ->will($this->returnValue($canSkipOrderReviewStep));
+        if ($canSkipOrderReviewStep) {
+            $this->_expectForwardPlaceOrder();
+        } else {
+            $this->_expectRedirect();
+        }
+        $this->model->execute();
+    }
+
+    private function _expectForwardPlaceOrder()
+    {
+        $this->request->expects($this->once())
+            ->method('setActionName')
+            ->with('placeOrder');
+        $this->request->expects($this->once())
+            ->method('setDispatched')
+            ->with(false);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/StartTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/StartTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..da573310e73386b1f3a360e8457ee350a63163f9
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/Express/StartTest.php
@@ -0,0 +1,62 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Paypal\Controller\Express;
+
+class StartTest extends \Magento\Paypal\Controller\ExpressTest
+{
+    protected $name = 'Start';
+
+    /**
+     * @param null|bool $buttonParam
+     * @dataProvider startActionDataProvider
+     */
+    public function testStartAction($buttonParam)
+    {
+        $this->request->expects($this->at(1))
+            ->method('getParam')
+            ->with('bml')
+            ->will($this->returnValue($buttonParam));
+        $this->checkout->expects($this->once())
+            ->method('setIsBml')
+            ->with((bool)$buttonParam);
+
+        $this->request->expects($this->at(2))
+            ->method('getParam')
+            ->with(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_BUTTON)
+            ->will($this->returnValue($buttonParam));
+        $this->customerData->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue(1));
+        $this->checkout->expects($this->once())
+            ->method('start')
+            ->with($this->anything(), $this->anything(), (bool)$buttonParam);
+        $this->model->execute();
+    }
+
+    public function startActionDataProvider()
+    {
+        return [['1'], [null]];
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Paypal/Controller/ExpressTest.php b/dev/tests/unit/testsuite/Magento/Paypal/Controller/ExpressTest.php
index 5e9b3fee891ee4a5a5ed9d55b41ddce29bdeb966..7f4def65996fcda057730fcb2eefc80c364ba084 100644
--- a/dev/tests/unit/testsuite/Magento/Paypal/Controller/ExpressTest.php
+++ b/dev/tests/unit/testsuite/Magento/Paypal/Controller/ExpressTest.php
@@ -29,11 +29,13 @@ use Magento\TestFramework\Helper\ObjectManager as ObjectManagerHelper;
 /**
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
-class ExpressTest extends \PHPUnit_Framework_TestCase
+abstract class ExpressTest extends \PHPUnit_Framework_TestCase
 {
     /** @var Express */
     protected $model;
 
+    protected $name = '';
+
     /** @var \Magento\Customer\Model\Session|\PHPUnit_Framework_MockObject_MockObject */
     protected $customerSession;
 
@@ -75,6 +77,7 @@ class ExpressTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
+        $this->markTestIncomplete();
         $this->messageManager = $this->getMockForAbstractClass('Magento\Framework\Message\ManagerInterface');
         $this->config = $this->getMock('Magento\Paypal\Model\Config', [], [], '', false);
         $this->request = $this->getMock('Magento\Framework\App\Request\Http', [], [], '', false);
@@ -119,7 +122,7 @@ class ExpressTest extends \PHPUnit_Framework_TestCase
 
         $helper = new ObjectManagerHelper($this);
         $this->model = $helper->getObject(
-            'Magento\Paypal\Controller\Express',
+            '\\Magento\\\Paypal\\Controller\\Express\\' . $this->name,
             [
                 'messageManager' => $this->messageManager,
                 'response' => $this->response,
@@ -133,223 +136,4 @@ class ExpressTest extends \PHPUnit_Framework_TestCase
             ]
         );
     }
-
-    /**
-     * @param null|bool $buttonParam
-     * @dataProvider startActionDataProvider
-     */
-    public function testStartAction($buttonParam)
-    {
-        $this->request->expects($this->at(1))
-            ->method('getParam')
-            ->with('bml')
-            ->will($this->returnValue($buttonParam));
-        $this->checkout->expects($this->once())
-            ->method('setIsBml')
-            ->with((bool)$buttonParam);
-
-        $this->request->expects($this->at(2))
-            ->method('getParam')
-            ->with(\Magento\Paypal\Model\Express\Checkout::PAYMENT_INFO_BUTTON)
-            ->will($this->returnValue($buttonParam));
-        $this->customerData->expects($this->any())
-            ->method('getId')
-            ->will($this->returnValue(1));
-        $this->checkout->expects($this->once())
-            ->method('start')
-            ->with($this->anything(), $this->anything(), (bool)$buttonParam);
-        $this->model->startAction();
-    }
-
-    public function startActionDataProvider()
-    {
-        return [['1'], [null]];
-    }
-
-    public function testReturnActionAuthorizationRetrial()
-    {
-        $this->request->expects($this->once())
-            ->method('getParam')
-            ->with('retry_authorization')
-            ->will($this->returnValue('true'));
-        $this->checkoutSession->expects($this->once())
-            ->method('__call')
-            ->with('getPaypalTransactionData')
-            ->will($this->returnValue(['any array']));
-        $this->_expectForwardPlaceOrder();
-        $this->model->returnAction();
-    }
-
-    /**
-     * @param bool $canSkipOrderReviewStep
-     * @dataProvider trueFalseDataProvider
-     */
-    public function testReturnAction($canSkipOrderReviewStep)
-    {
-        $this->checkoutSession->expects($this->at(0))
-            ->method('__call')
-            ->with('unsPaypalTransactionData');
-        $this->checkout->expects($this->once())
-            ->method('canSkipOrderReviewStep')
-            ->will($this->returnValue($canSkipOrderReviewStep));
-        if ($canSkipOrderReviewStep) {
-            $this->_expectForwardPlaceOrder();
-        } else {
-            $this->_expectRedirect();
-        }
-        $this->model->returnAction();
-    }
-
-    public function trueFalseDataProvider()
-    {
-        return [[true], [false]];
-    }
-
-    /**
-     * @param bool $isGeneral
-     * @dataProvider trueFalseDataProvider
-     */
-    public function testPlaceOrderActionNonProcessableException($isGeneral)
-    {
-        if (!$isGeneral) {
-            $this->request->expects($this->once())
-                ->method('getPost')
-                ->with('agreement', [])
-                ->will($this->returnValue([]));
-        }
-        $this->_expectRedirect();
-        $this->model->placeOrderAction();
-    }
-
-    /**
-     * @param int $code
-     * @param null|string $paymentAction
-     * @dataProvider placeOrderActionProcessableExceptionDataProvider
-     */
-    public function testPlaceOrderActionProcessableException($code, $paymentAction = null)
-    {
-        $this->request->expects($this->once())
-            ->method('getPost')
-            ->with('agreement', [])
-            ->will($this->returnValue([]));
-        $oldCallback = &$this->objectManagerCallback;
-        $this->objectManagerCallback = function ($className) use ($code, $oldCallback) {
-            $instance = call_user_func($oldCallback, $className);
-            if ($className == 'Magento\Checkout\Model\Agreements\AgreementsValidator') {
-                $exception = $this->getMock(
-                    'Magento\Paypal\Model\Api\ProcessableException',
-                    ['getUserMessage'],
-                    ['message', $code]
-                );
-                $exception->expects($this->any())
-                    ->method('getUserMessage')
-                    ->will($this->returnValue('User Message'));
-                $instance->expects($this->once())
-                    ->method('isValid')
-                    ->will($this->throwException($exception));
-            }
-            return $instance;
-        };
-        if (isset($paymentAction)) {
-            $this->config->expects($this->once())
-                ->method('getPaymentAction')
-                ->will($this->returnValue($paymentAction));
-        }
-        $this->_expectErrorCodes($code, $paymentAction);
-        $this->model->placeOrderAction();
-    }
-
-    public function placeOrderActionProcessableExceptionDataProvider()
-    {
-        return [
-            [\Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED],
-            [\Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED],
-            [\Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL],
-            [
-                \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE,
-                \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
-            ],
-            [\Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE, 'other'],
-            [999999],
-        ];
-    }
-
-    private function _expectForwardPlaceOrder()
-    {
-        $this->request->expects($this->once())
-            ->method('setActionName')
-            ->with('placeOrder');
-        $this->request->expects($this->once())
-            ->method('setDispatched')
-            ->with(false);
-    }
-
-    /**
-     * @param string $path
-     */
-    private function _expectRedirect($path = '*/*/review')
-    {
-        $this->redirect->expects($this->once())
-            ->method('redirect')
-            ->with($this->anything(), $path, []);
-    }
-
-    /**
-     * @param int $code
-     * @param null|string $paymentAction
-     */
-    private function _expectErrorCodes($code, $paymentAction)
-    {
-        $redirectUrl = 'redirect by test';
-        if (in_array(
-            $code,
-            [
-                \Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED,
-                \Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED,
-            ]
-        )
-        ) {
-            $payment = new \Magento\Framework\Object(['checkout_redirect_url' => $redirectUrl]);
-            $this->quote->expects($this->once())
-                ->method('getPayment')
-                ->will($this->returnValue($payment));
-        }
-        if ($code == \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE
-            && $paymentAction == \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
-        ) {
-            $this->config->expects($this->once())
-                ->method('getExpressCheckoutOrderUrl')
-                ->will($this->returnValue($redirectUrl));
-        }
-        if ($code == \Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL
-            || $code == \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE
-            && $paymentAction != \Magento\Payment\Model\Method\AbstractMethod::ACTION_ORDER
-        ) {
-            $this->config->expects($this->once())
-                ->method('getExpressCheckoutStartUrl')
-                ->will($this->returnValue($redirectUrl));
-            $this->request->expects($this->once())
-                ->method('getParam')
-                ->with('token');
-        }
-        if (in_array(
-            $code,
-            [
-                \Magento\Paypal\Model\Api\ProcessableException::API_MAX_PAYMENT_ATTEMPTS_EXCEEDED,
-                \Magento\Paypal\Model\Api\ProcessableException::API_TRANSACTION_EXPIRED,
-                \Magento\Paypal\Model\Api\ProcessableException::API_DO_EXPRESS_CHECKOUT_FAIL,
-                \Magento\Paypal\Model\Api\ProcessableException::API_UNABLE_TRANSACTION_COMPLETE,
-            ]
-        )
-        ) {
-            $this->response->expects($this->once())
-                ->method('setRedirect')
-                ->with($redirectUrl);
-        } else {
-            $this->messageManager->expects($this->once())
-                ->method('addError')
-                ->with('User Message');
-            $this->_expectRedirect('checkout/cart');
-        }
-    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php b/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/Product/PostTest.php
similarity index 97%
rename from dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php
rename to dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/Product/PostTest.php
index cc5e0baa021f6465a218db9f11f3e78e20733589..0629194aa7e4f3477b57380c391432c198574ac0 100644
--- a/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/ProductTest.php
+++ b/dev/tests/unit/testsuite/Magento/Review/Controller/Adminhtml/Product/PostTest.php
@@ -22,12 +22,12 @@
  * @license http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
 
-namespace Magento\Review\Controller\Adminhtml;
+namespace Magento\Review\Controller\Adminhtml\Product;
 
 /**
  * @SuppressWarnings(PHPMD.TooManyFields)
  */
-class ProductTest extends \PHPUnit_Framework_TestCase
+class PostTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Review\Controller\Adminhtml\Product
@@ -113,7 +113,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $objectManagerHelper = new \Magento\TestFramework\Helper\ObjectManager($this);
 
         $this->_model = $objectManagerHelper->getObject(
-            'Magento\Review\Controller\Adminhtml\Product',
+            'Magento\Review\Controller\Adminhtml\Product\Post',
             [
                 'coreRegistry' => $this->_registryMock,
                 'reviewFactory' => $this->_reviewFactoryMock,
@@ -229,7 +229,7 @@ class ProductTest extends \PHPUnit_Framework_TestCase
         $this->_helperMock->expects($this->once())->method('geturl')
             ->will($this->returnValue('url'));
 
-        $this->_model->postAction();
+        $this->_model->execute();
     }
 
 }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreditmemoTest.php b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/SaveTest.php
similarity index 82%
rename from dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreditmemoTest.php
rename to dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/SaveTest.php
index 3b698b23799c94d4ca8e752233b5f9034909873d..b6f5262d597be49926ea76790757f2104e6222a9 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/CreditmemoTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/Creditmemo/SaveTest.php
@@ -21,9 +21,9 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml\Order;
+namespace Magento\Sales\Controller\Adminhtml\Order\Creditmemo;
 
-class CreditmemoTest extends \PHPUnit_Framework_TestCase
+class SaveTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\Sales\Controller\Adminhtml\Order\Creditmemo
@@ -55,6 +55,11 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
      */
     protected $_messageManager;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $memoLoaderMock;
+
     /**
      * Init model for future tests
      */
@@ -103,9 +108,12 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
 
         $context = $helper->getObject('Magento\Backend\App\Action\Context', $arguments);
 
+        $this->memoLoaderMock = $this->getMock(
+            '\Magento\Sales\Controller\Adminhtml\Order\CreditmemoLoader', array(), array(), '', false
+        );
         $this->_controller = $helper->getObject(
-            'Magento\Sales\Controller\Adminhtml\Order\Creditmemo',
-            array('context' => $context)
+            'Magento\Sales\Controller\Adminhtml\Order\Creditmemo\Save',
+            array('context' => $context, 'creditmemoLoader' => $this->memoLoaderMock)
         );
     }
 
@@ -115,7 +123,6 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
     public function testSaveActionOnlineRefundToStoreCredit()
     {
         $data = array('comment_text' => '', 'do_offline' => '0', 'refund_customerbalance_return_enable' => '1');
-        $creditmemoId = '1';
         $this->_requestMock->expects(
             $this->once()
         )->method(
@@ -125,15 +132,6 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue($data)
         );
-        $this->_requestMock->expects(
-            $this->at(1)
-        )->method(
-            'getParam'
-        )->with(
-            'creditmemo_id'
-        )->will(
-            $this->returnValue($creditmemoId)
-        );
         $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(null));
 
         $creditmemoMock = $this->getMock(
@@ -143,22 +141,11 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $creditmemoMock->expects(
-            $this->once()
-        )->method(
-            'load'
-        )->with(
-            $this->equalTo($creditmemoId)
-        )->will(
-            $this->returnSelf()
-        );
         $creditmemoMock->expects($this->once())->method('getGrandTotal')->will($this->returnValue('1'));
-        $this->_objectManager->expects(
+        $this->memoLoaderMock->expects(
             $this->once()
         )->method(
-            'create'
-        )->with(
-            $this->equalTo('Magento\Sales\Model\Order\Creditmemo')
+            'load'
         )->will(
             $this->returnValue($creditmemoMock)
         );
@@ -168,7 +155,7 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
             'Cannot create online refund for Refund to Store Credit.'
         );
 
-        $this->_controller->saveAction();
+        $this->_controller->execute();
     }
 
     /**
@@ -177,7 +164,6 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
     public function testSaveActionWithNegativeCreditmemo()
     {
         $data = array('comment_text' => '');
-        $creditmemoId = '1';
         $this->_requestMock->expects(
             $this->once()
         )->method(
@@ -187,15 +173,6 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue($data)
         );
-        $this->_requestMock->expects(
-            $this->at(1)
-        )->method(
-            'getParam'
-        )->with(
-            'creditmemo_id'
-        )->will(
-            $this->returnValue($creditmemoId)
-        );
         $this->_requestMock->expects($this->any())->method('getParam')->will($this->returnValue(null));
 
         $creditmemoMock = $this->getMock(
@@ -205,30 +182,19 @@ class CreditmemoTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-        $creditmemoMock->expects(
-            $this->once()
-        )->method(
-            'load'
-        )->with(
-            $this->equalTo($creditmemoId)
-        )->will(
-            $this->returnSelf()
-        );
         $creditmemoMock->expects($this->once())->method('getGrandTotal')->will($this->returnValue('0'));
         $creditmemoMock->expects($this->once())->method('getAllowZeroGrandTotal')->will($this->returnValue(false));
-        $this->_objectManager->expects(
+        $this->memoLoaderMock->expects(
             $this->once()
         )->method(
-            'create'
-        )->with(
-            $this->equalTo('Magento\Sales\Model\Order\Creditmemo')
+            'load'
         )->will(
             $this->returnValue($creditmemoMock)
         );
 
         $this->_setSaveActionExpectationForMageCoreException($data, 'Credit memo\'s total must be positive.');
 
-        $this->_controller->saveAction();
+        $this->_controller->execute();
     }
 
     /**
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/OrderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/ViewTest.php
similarity index 95%
rename from dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/OrderTest.php
rename to dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/ViewTest.php
index afb5d98498f7e77229a5e254c9eed622f4ed3b37..a7b86de0c7dee389e02c7bd8cfcf69bab972b93d 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/OrderTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Controller/Adminhtml/Order/ViewTest.php
@@ -21,14 +21,14 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Sales\Controller\Adminhtml;
+namespace Magento\Sales\Controller\Adminhtml\Order;
 
 use Magento\Backend\App\Action;
 
 /**
  * Magento Adminhtml Order Controller Test
  */
-class OrderTest extends \PHPUnit_Framework_TestCase
+class ViewTest extends \PHPUnit_Framework_TestCase
 {
     /**
      * @var \Magento\TestFramework\Helper\ObjectManager
@@ -85,7 +85,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase
          *  - Protected properties MUST NOT be set from outside, inject via context passed to constructor instead
          */
         $this->_controllerMock = $this->getMockBuilder(
-            '\Magento\Sales\Controller\Adminhtml\Order'
+            '\Magento\Sales\Controller\Adminhtml\Order\View'
         )->disableOriginalConstructor()->setMethods(
             array('__wakeup', '_initOrder', '_initAction', '__', 'renderLayout', '_redirect')
         )->getMock();
@@ -131,7 +131,7 @@ class OrderTest extends \PHPUnit_Framework_TestCase
         );
         $this->_orderMock->expects($this->never())->method('getRealOrderId');
 
-        $this->_controllerMock->viewAction();
+        $this->_controllerMock->execute();
     }
 
     /**
@@ -151,6 +151,6 @@ class OrderTest extends \PHPUnit_Framework_TestCase
         $this->_messageMock->expects($this->never())->method('addError');
         $this->_orderMock->expects($this->once())->method('getRealOrderId')->will($this->returnValue(1));
 
-        $this->_controllerMock->viewAction();
+        $this->_controllerMock->execute();
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
index 651fa08f909c293a12716d2b467ed3db736b5f61..539dbabda3fe80ad61b4da22103fe5e25566d2fe 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/CreateTest.php
@@ -47,6 +47,9 @@ class CreateTest extends \PHPUnit_Framework_TestCase
     /** @var \Magento\Customer\Service\V1\CustomerGroupServiceInterface|\PHPUnit_Framework_MockObject_MockObject */
     protected $customerGroupServiceMock;
 
+    /** @var \Magento\Sales\Model\Quote\Item\Updater|\PHPUnit_Framework_MockObject_MockObject */
+    protected $itemUpdater;
+
     protected function setUp()
     {
         $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager');
@@ -83,6 +86,8 @@ class CreateTest extends \PHPUnit_Framework_TestCase
         $customerHelperMock = $this->getMock('Magento\Customer\Helper\Data', array(), array(), '', false);
         $this->customerGroupServiceMock = $this->getMock('Magento\Customer\Service\V1\CustomerGroupServiceInterface');
 
+        $this->itemUpdater = $this->getMock('Magento\Sales\Model\Quote\Item\Updater', array(), array(), '', false);
+
         $objectManagerHelper = new ObjectManagerHelper($this);
         $this->adminOrderCreate = $objectManagerHelper->getObject(
             'Magento\Sales\Model\AdminOrder\Create',
@@ -101,7 +106,8 @@ class CreateTest extends \PHPUnit_Framework_TestCase
                 'metadataFormFactory' => $this->formFactoryMock,
                 'customerBuilder' => $this->customerBuilderMock,
                 'customerHelper' => $customerHelperMock,
-                'customerGroupService' => $this->customerGroupServiceMock
+                'customerGroupService' => $this->customerGroupServiceMock,
+                'quoteItemUpdater' => $this->itemUpdater
             )
         );
     }
@@ -192,4 +198,68 @@ class CreateTest extends \PHPUnit_Framework_TestCase
 
         $this->adminOrderCreate->setAccountData(array());
     }
+
+    public function testUpdateQuoteItemsNotArray()
+    {
+        $this->adminOrderCreate->updateQuoteItems('string');
+    }
+
+    public function testUpdateQuoteItemsEmptyConfiguredOption()
+    {
+        $items = array(
+            1 => array(
+                'qty' => 10,
+                'configured' => false,
+                'action' => false
+            )
+        );
+
+        $itemMock = $this->getMock('Magento\Sales\Model\Quote\Item', array(), array(), '', false);
+
+        $quoteMock = $this->getMock('Magento\Sales\Model\Quote', array(), array(), '', false);
+        $quoteMock->expects($this->once())
+            ->method('getItemById')
+            ->will($this->returnValue($itemMock));
+
+        $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock));
+        $this->itemUpdater->expects($this->once())
+            ->method('update')
+            ->with($this->equalTo($itemMock), $this->equalTo($items[1]));
+
+        $this->adminOrderCreate->setRecollect(false);
+        $this->adminOrderCreate->updateQuoteItems($items);
+    }
+
+    public function testUpdateQuoteItemsWithConfiguredOption()
+    {
+        $qty = 100000000;
+        $items = array(
+            1 => array(
+                'qty' => 10,
+                'configured' => true,
+                'action' => false
+            )
+        );
+
+        $itemMock = $this->getMock('Magento\Sales\Model\Quote\Item', array(), array(), '', false);
+        $itemMock->expects($this->once())
+            ->method('getQty')
+            ->will($this->returnValue($qty));
+
+        $quoteMock = $this->getMock('Magento\Sales\Model\Quote', array(), array(), '', false);
+        $quoteMock->expects($this->once())
+            ->method('updateItem')
+            ->will($this->returnValue($itemMock));
+
+        $this->sessionQuoteMock->expects($this->any())->method('getQuote')->will($this->returnValue($quoteMock));
+
+        $expectedInfo = $items[1];
+        $expectedInfo['qty'] = $qty;
+        $this->itemUpdater->expects($this->once())
+            ->method('update')
+            ->with($this->equalTo($itemMock), $this->equalTo($expectedInfo));
+
+        $this->adminOrderCreate->setRecollect(false);
+        $this->adminOrderCreate->updateQuoteItems($items);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..8899af9c4555e50c3a077d5986c653b8678744bf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/EmailSenderTest.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\AdminOrder;
+
+class EmailSenderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $loggerMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManagerMock;
+
+    /**
+     * @var EmailSender
+     */
+    protected $emailSender;
+
+    protected function setUp()
+    {
+        $this->messageManagerMock = $this->getMock(
+            '\Magento\Framework\Message\Manager',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->loggerMock = $this->getMock(
+            '\Magento\Framework\Logger',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->orderMock = $this->getMock(
+            '\Magento\Sales\Model\Order',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->emailSender = new EmailSender($this->messageManagerMock, $this->loggerMock);
+    }
+
+    public function testSendSuccess()
+    {
+        $this->orderMock->expects($this->once())
+            ->method('sendNewOrderEmail');
+        $this->assertTrue($this->emailSender->send($this->orderMock));
+    }
+
+    public function testSendFailure()
+    {
+        $this->orderMock->expects($this->once())
+            ->method('sendNewOrderEmail')
+            ->will($this->throwException(new \Magento\Framework\Mail\Exception('test message')));
+        $this->messageManagerMock->expects($this->once())
+            ->method('addWarning');
+        $this->loggerMock->expects($this->once())
+            ->method('logException');
+
+        $this->assertFalse($this->emailSender->send($this->orderMock));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php
index 07aa134b4af86def437ddb12ad9fd1ca5694385f..2be65785a1726651fe0c073d4261922019f367c3 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/AdminOrder/Product/Quote/InitializerTest.php
@@ -63,7 +63,7 @@ class InitializerTest extends \PHPUnit_Framework_TestCase
     {
         $this->quoteMock = $this->getMock(
             'Magento\Sales\Model\Quote',
-            ['addProductAdvanced', '__wakeup'],
+            ['addProduct', '__wakeup'],
             [],
             '',
             false
@@ -135,7 +135,7 @@ class InitializerTest extends \PHPUnit_Framework_TestCase
             ->method('setQty');
 
         $this->quoteMock->expects($this->once())
-            ->method('addProductAdvanced')
+            ->method('addProduct')
             ->will($this->returnValue($quoteItemMock));
 
         $this->assertInstanceOf(
@@ -183,7 +183,7 @@ class InitializerTest extends \PHPUnit_Framework_TestCase
 
 
         $this->quoteMock->expects($this->once())
-            ->method('addProductAdvanced')
+            ->method('addProduct')
             ->will($this->returnValue($quoteItemMock));
 
         $this->assertInstanceOf(
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/ProcessorTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/ProcessorTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6558883fbb5e736bd5394d99cb5cf75354b668a0
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/ProcessorTest.php
@@ -0,0 +1,285 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Quote\Item;
+
+use \Magento\Catalog\Model\Product;
+use \Magento\Sales\Model\Quote\ItemFactory;
+use \Magento\Sales\Model\Quote\Item;
+use \Magento\Store\Model\StoreManagerInterface;
+use \Magento\Store\Model\Store;
+use \Magento\Framework\App\State;
+use \Magento\Framework\Object;
+
+/**
+ * Tests for Magento\Sales\Model\Service\Quote\Processor
+ */
+class ProcessorTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Processor
+     */
+    protected $processor;
+
+    /**
+     * @var ItemFactory |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteItemFactoryMock;
+
+    /**
+     * @var StoreManagerInterface |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var State |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stateMock;
+
+    /**
+     * @var Product |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var Object |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectMock;
+
+    /**
+     * @var Item |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $itemMock;
+
+    /**
+     * @var Store |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
+    protected function setUp()
+    {
+        $this->quoteItemFactoryMock = $this->getMock(
+            'Magento\Sales\Model\Quote\ItemFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+
+        $this->itemMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Item',
+            ['getId', 'setOptions', '__wakeup', 'setProduct', 'addQty', 'setCustomPrice', 'setOriginalCustomPrice'],
+            [],
+            '',
+            false
+        );
+        $this->quoteItemFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($this->itemMock));
+
+        $this->storeManagerMock = $this->getMock(
+            'Magento\Store\Model\StoreManager',
+            ['getStore'],
+            [],
+            '',
+            false
+        );
+        $this->storeMock = $this->getMock('Magento\Store\Model\Store', ['getId', '__wakeup'], [], '', false);
+        $this->storeManagerMock->expects($this->any())
+            ->method('getStore')
+            ->will($this->returnValue($this->storeMock));
+
+        $this->stateMock = $this->getMock(
+            'Magento\Framework\App\State',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $this->processor = new Processor(
+            $this->quoteItemFactoryMock,
+            $this->storeManagerMock,
+            $this->stateMock
+        );
+
+        $this->productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            ['getCustomOptions', '__wakeup', 'getParentProductId'],
+            [],
+            '',
+            false
+        );
+        $this->objectMock = $this->getMock(
+            'Magento\Framework\Object',
+            ['getResetCount', 'getId', 'getCustomPrice'],
+            [],
+            '',
+            false
+        );
+    }
+
+    public function testInitWithQtyModification()
+    {
+        $storeId = 1000000000;
+        $productCustomOptions = 'test_custom_options';
+        $requestId = 20000000;
+        $itemId = $requestId;
+
+        $this->productMock->expects($this->any())
+            ->method('getCustomOptions')
+            ->will($this->returnValue($productCustomOptions));
+        $this->productMock->expects($this->any())
+            ->method('getStickWithinParent')
+            ->will($this->returnValue(false));
+
+        $this->itemMock->expects($this->any())
+            ->method('setOptions')
+            ->will($this->returnValue($productCustomOptions));
+        $this->itemMock->expects($this->any())
+            ->method('setProduct')
+            ->will($this->returnValue($this->productMock));
+        $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->any())
+            ->method('setData')
+            ->with($this->equalTo('qty'), $this->equalTo(0));
+
+
+        $this->storeMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+
+        $this->objectMock->expects($this->any())
+            ->method('getResetCount')
+            ->will($this->returnValue(true));
+        $this->objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($requestId));
+
+        $this->processor->init($this->productMock, $this->objectMock);
+    }
+
+    public function testInitWithoutModification()
+    {
+        $storeId = 1000000000;
+        $itemId = 2000000000;
+
+        $this->productMock->expects($this->never())->method('getCustomOptions');
+        $this->productMock->expects($this->never())->method('getStickWithinParent');
+
+        $this->productMock->expects($this->any())
+            ->method('getParentProductId')
+            ->will($this->returnValue(true));
+
+
+        $this->itemMock->expects($this->never())->method('setOptions');
+        $this->itemMock->expects($this->never())->method('setProduct');
+
+        $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+
+        $this->itemMock->expects($this->never())->method('setData');
+
+        $this->storeMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+
+        $this->objectMock->expects($this->never())->method('getResetCount');
+        $this->objectMock->expects($this->never())->method('getId');
+
+        $this->processor->init($this->productMock, $this->objectMock);
+    }
+
+    public function testInitWithoutModificationAdminhtmlAreaCode()
+    {
+        $areaCode = \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE;
+        $storeId = 1000000000;
+        $requestId = 20000000;
+        $itemId = $requestId;
+
+        $this->stateMock->expects($this->any())
+            ->method('getAreaCode')
+            ->will($this->returnValue($areaCode));
+
+        $this->productMock->expects($this->never())->method('getCustomOptions');
+        $this->productMock->expects($this->never())->method('getStickWithinParent');
+
+        $this->productMock->expects($this->any())
+            ->method('getParentProductId')
+            ->will($this->returnValue(true));
+
+        $this->itemMock->expects($this->never())->method('setOptions');
+        $this->itemMock->expects($this->never())->method('setProduct');
+
+        $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+
+        $this->itemMock->expects($this->never())->method('setData');
+
+        $this->storeMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($storeId));
+
+        $this->objectMock->expects($this->never())->method('getResetCount');
+        $this->objectMock->expects($this->never())->method('getId');
+
+        $this->processor->init($this->productMock, $this->objectMock);
+    }
+
+    public function testPrepare()
+    {
+        $qty = 3000000000;
+        $customPrice = 400000000;
+
+        $this->itemMock->expects($this->any())
+            ->method('addQty')
+            ->will($this->returnValue($qty));
+
+        $this->itemMock->expects($this->any())
+            ->method('setCustomPrice')
+            ->will($this->returnValue($customPrice));
+
+        $this->itemMock->expects($this->any())
+            ->method('setOriginalCustomPrice')
+            ->will($this->returnValue($customPrice));
+
+        $this->itemMock->expects($this->any())
+            ->method('addQty')
+            ->will($this->returnValue($qty));
+
+
+        $this->productMock->expects($this->any())
+            ->method('getCartQty')
+            ->will($this->returnValue($qty));
+
+        $this->objectMock->expects($this->any())
+            ->method('getCustomPrice')
+            ->will($this->returnValue($customPrice));
+
+        $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/UpdaterTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/UpdaterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e5abca9ce150b031a508be66cbc533217c2c4d6
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/Quote/Item/UpdaterTest.php
@@ -0,0 +1,394 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Sales\Model\Quote\Item;
+
+use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Sales\Model\Quote\Item\Updater;
+
+/**
+ * Tests  for Magento\Sales\Model\Service\Quote\Updater
+ *
+ */
+class UpdaterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sales\Model\Quote\Item\Updater |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $object;
+
+    /**
+     * @var \Magento\Sales\Model\Quote\Item |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $itemMock;
+
+    /**
+     * @var \Magento\CatalogInventory\Model\Stock\Item |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $stockItemMock;
+
+    /**
+     * @var \Magento\Framework\Locale\Format |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $localeFormat;
+
+    /**
+     * @var \Magento\Catalog\Model\Product |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    protected function setUp()
+    {
+        $this->productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            [
+                'getStockItem',
+                '__wakeup',
+                'setIsSuperMode',
+                'unsSkipCheckRequiredOption'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->localeFormat = $this->getMock(
+            'Magento\Framework\Locale\Format',
+            [
+                'getNumber', 'getPriceFormat'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->itemMock = $this->getMock(
+            'Magento\Sales\Model\Quote\Item',
+            [
+                'updateItem',
+                'getProduct',
+                'setQty',
+                'setNoDiscount',
+                'checkData',
+                '__wakeup',
+                'getBuyRequest',
+                'addOption',
+                'setCustomPrice',
+                'setOriginalCustomPrice',
+                'unsetData',
+                'hasData'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->stockItemMock = $this->getMock(
+            'Magento\CatalogInventory\Model\Stock\Item',
+            [
+                'getIsQtyDecimal',
+                '__wakeup'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $this->object = (new ObjectManager($this))
+            ->getObject(
+                'Magento\Sales\Model\Quote\Item\Updater',
+                [
+                    'localeFormat' => $this->localeFormat
+                ]
+            );
+    }
+
+    /**
+     * @expectedException \InvalidArgumentException
+     * @ExceptedExceptionMessage The qty value is required to update quote item.
+     */
+    public function testUpdateNoQty()
+    {
+        $this->object->update($this->itemMock, []);
+    }
+
+    /**
+     * @dataProvider qtyProvider
+     */
+    public function testUpdateNotQtyDecimal($qty, $expectedQty)
+    {
+        $this->itemMock->expects($this->any())
+            ->method('setNoDiscount')
+            ->will($this->returnValue(true));
+
+        $this->itemMock->expects($this->any())
+            ->method('setQty')
+            ->with($this->equalTo($expectedQty));
+
+        $this->productMock->expects($this->any())
+            ->method('getStockItem')
+            ->will($this->returnValue($this->stockItemMock));
+
+        $this->productMock->expects($this->any())
+            ->method('setIsSuperMode')
+            ->with($this->equalTo(true));
+        $this->productMock->expects($this->any())
+            ->method('unsSkipCheckRequiredOption');
+
+        $this->itemMock->expects($this->any())
+            ->method('getProduct')
+            ->will($this->returnValue($this->productMock));
+
+        $this->object->update($this->itemMock, ['qty' => $qty]);
+    }
+
+    public function qtyProvider()
+    {
+        return [
+            [1, 1],
+            [5.66, 5],
+            ['test', 1],
+            [-3, 1],
+            [0, 1],
+            [-2.99, 1]
+        ];
+    }
+
+    public function qtyProviderDecimal()
+    {
+        return [
+            [1, 1],
+            [5.66, 5.66],
+            ['test', 1],
+            [-3, 1],
+            [0, 1],
+            [-2.99, 1]
+        ];
+    }
+
+    /**
+     * @dataProvider qtyProviderDecimal
+     */
+    public function testUpdateQtyDecimal($qty, $expectedQty)
+    {
+        $this->itemMock->expects($this->any())
+            ->method('setNoDiscount')
+            ->will($this->returnValue(true));
+
+        $this->itemMock->expects($this->any())
+            ->method('setQty')
+            ->with($this->equalTo($expectedQty));
+
+        $this->itemMock->expects($this->any())
+            ->method('setIsQtyDecimal')
+            ->will($this->returnValue(true));
+
+        $this->stockItemMock->expects($this->any())
+            ->method('getIsQtyDecimal')
+            ->will($this->returnValue(true));
+
+        $this->productMock->expects($this->any())
+            ->method('getStockItem')
+            ->will($this->returnValue($this->stockItemMock));
+
+        $this->productMock->expects($this->any())
+            ->method('setIsSuperMode')
+            ->with($this->equalTo(true));
+        $this->productMock->expects($this->any())
+            ->method('unsSkipCheckRequiredOption');
+
+        $this->itemMock->expects($this->any())
+            ->method('getProduct')
+            ->will($this->returnValue($this->productMock));
+
+        $this->object->update($this->itemMock, ['qty' => $qty]);
+    }
+
+
+    public function testUpdateQtyDecimalWithConfiguredOption()
+    {
+        $this->itemMock->expects($this->any())
+            ->method('setIsQtyDecimal')
+            ->with($this->equalTo(1));
+
+        $this->stockItemMock->expects($this->any())
+            ->method('getIsQtyDecimal')
+            ->will($this->returnValue(true));
+
+        $this->productMock->expects($this->any())
+            ->method('getStockItem')
+            ->will($this->returnValue($this->stockItemMock));
+
+        $this->itemMock->expects($this->any())
+            ->method('getProduct')
+            ->will($this->returnValue($this->productMock));
+
+        $this->object->update($this->itemMock, ['qty' => 3, 'use_discount' => true]);
+    }
+
+    public function testUpdateCustomPrice()
+    {
+        $customPrice = 9.99;
+        $qty = 3;
+        $buyRequestMock = $this->getMock(
+            'Magento\Framework\Object',
+            [
+                'setCustomPrice',
+                'setValue',
+                'setCode',
+                'setProduct',
+                'getData'
+            ],
+            [],
+            '',
+            false
+        );
+        $buyRequestMock->expects($this->any())
+            ->method('setCustomPrice')
+            ->with($this->equalTo($customPrice));
+        $buyRequestMock->expects($this->any())
+            ->method('getData')
+            ->will($this->returnValue(['custom_price' => $customPrice]));
+
+        $buyRequestMock->expects($this->any())
+            ->method('setValue')
+            ->with($this->equalTo(serialize(['custom_price' => $customPrice])));
+        $buyRequestMock->expects($this->any())
+            ->method('setCode')
+            ->with($this->equalTo('info_buyRequest'));
+
+        $buyRequestMock->expects($this->any())
+            ->method('setProduct')
+            ->with($this->equalTo($this->productMock));
+
+        $this->itemMock->expects($this->any())
+            ->method('setIsQtyDecimal')
+            ->with($this->equalTo(1));
+        $this->itemMock->expects($this->any())
+            ->method('getBuyRequest')
+            ->will($this->returnValue($buyRequestMock));
+
+        $this->stockItemMock->expects($this->any())
+            ->method('getIsQtyDecimal')
+            ->will($this->returnValue(true));
+
+
+        $this->productMock->expects($this->any())
+            ->method('getStockItem')
+            ->will($this->returnValue($this->stockItemMock));
+
+        $this->itemMock->expects($this->any())
+            ->method('getProduct')
+            ->will($this->returnValue($this->productMock));
+        $this->itemMock->expects($this->any())
+            ->method('addOption')
+            ->will($this->returnValue($buyRequestMock));
+        $this->itemMock->expects($this->any())
+            ->method('setQty')
+            ->with($this->equalTo($qty));
+
+        $this->localeFormat->expects($this->any())
+            ->method('getNumber')
+            ->will($this->returnArgument(0));
+
+        $this->object->update($this->itemMock, ['qty' => $qty, 'custom_price' => $customPrice]);
+    }
+
+    public function testUpdateUnsetCustomPrice()
+    {
+        $qty = 3;
+        $buyRequestMock = $this->getMock(
+            'Magento\Framework\Object',
+            [
+                'setCustomPrice',
+                'setValue',
+                'setCode',
+                'setProduct',
+                'getData',
+                'unsetData',
+                'hasData'
+            ],
+            [],
+            '',
+            false
+        );
+        $buyRequestMock->expects($this->never())->method('setCustomPrice');
+        $buyRequestMock->expects($this->once())->method('getData')->will($this->returnValue([]));
+        $buyRequestMock->expects($this->once())->method('unsetData')->with($this->equalTo('custom_price'));
+        $buyRequestMock->expects($this->once())
+            ->method('hasData')
+            ->with($this->equalTo('custom_price'))
+            ->will($this->returnValue(true));
+
+        $buyRequestMock->expects($this->any())
+            ->method('setValue')
+            ->with($this->equalTo(serialize([])));
+        $buyRequestMock->expects($this->any())
+            ->method('setCode')
+            ->with($this->equalTo('info_buyRequest'));
+
+        $buyRequestMock->expects($this->any())
+            ->method('setProduct')
+            ->with($this->equalTo($this->productMock));
+
+        $this->itemMock->expects($this->any())
+            ->method('setIsQtyDecimal')
+            ->with($this->equalTo(1));
+        $this->itemMock->expects($this->any())
+            ->method('getBuyRequest')
+            ->will($this->returnValue($buyRequestMock));
+
+        $this->stockItemMock->expects($this->any())
+            ->method('getIsQtyDecimal')
+            ->will($this->returnValue(true));
+
+
+        $this->productMock->expects($this->any())
+            ->method('getStockItem')
+            ->will($this->returnValue($this->stockItemMock));
+
+        $this->itemMock->expects($this->any())
+            ->method('getProduct')
+            ->will($this->returnValue($this->productMock));
+        $this->itemMock->expects($this->any())
+            ->method('addOption')
+            ->will($this->returnValue($buyRequestMock));
+
+        $this->itemMock->expects($this->exactly(2))
+            ->method('unsetData');
+
+        $this->itemMock->expects($this->once())
+            ->method('hasData')
+            ->with($this->equalTo('custom_price'))
+            ->will($this->returnValue(true));
+
+        $this->itemMock->expects($this->never())->method('setCustomPrice');
+        $this->itemMock->expects($this->never())->method('setOriginalCustomPrice');
+
+        $this->localeFormat->expects($this->any())
+            ->method('getNumber')
+            ->will($this->returnArgument(0));
+
+        $this->object->update($this->itemMock, ['qty' => $qty]);
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php b/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
index 06e38508367f25e6ecd7412cdab62d7e3b2e85cb..4142abbadf8586bc02f2e253253f1694ad4cb6e1 100644
--- a/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
+++ b/dev/tests/unit/testsuite/Magento/Sales/Model/QuoteTest.php
@@ -86,6 +86,21 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
      */
     protected $quote;
 
+    /**
+     * @var \Magento\Catalog\Model\Product |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productMock;
+
+    /**
+     * @var \Magento\Framework\Object\Factory |\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectFactoryMock;
+
+    /**
+     * @var \Magento\Sales\Model\Resource\Quote\Item\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $quoteItemCollectionFactoryMock;
+
     protected function setUp()
     {
         $this->quoteAddressFactoryMock = $this->getMock(
@@ -117,7 +132,8 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
-
+        $this->productMock = $this->getMock('\Magento\Catalog\Model\Product', [], [], '', false);
+        $this->objectFactoryMock = $this->getMock('\Magento\Framework\Object\Factory', ['create'], [], '', false);
         $this->quoteAddressFactoryMock->expects(
             $this->any()
         )->method(
@@ -132,11 +148,9 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         )->will(
             $this->returnValue($this->quoteAddressCollectionMock)
         );
-
         $this->eventManagerMock = $this->getMockBuilder('Magento\Framework\Event\Manager')
             ->disableOriginalConstructor()
             ->getMock();
-
         $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManager')
             ->disableOriginalConstructor()
             ->getMock();
@@ -159,8 +173,13 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         $this->contextMock->expects($this->any())
             ->method('getEventDispatcher')
             ->will($this->returnValue($this->eventManagerMock));
-
-
+        $this->quoteItemCollectionFactoryMock = $this->getMock(
+            'Magento\Sales\Model\Resource\Quote\Item\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
         $this->quote = (
         new ObjectManager(
             $this
@@ -174,7 +193,9 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
                     'context' => $this->contextMock,
                     'customerFactory' => $this->customerFactoryMock,
                     'addressConverter' => $this->addressConverterMock,
-                    'customerGroupService' => $this->customerGroupServiceMock
+                    'customerGroupService' => $this->customerGroupServiceMock,
+                    'objectFactory' => $this->objectFactoryMock,
+                    'quoteItemCollectionFactory' => $this->quoteItemCollectionFactoryMock
                 ]
             );
     }
@@ -677,4 +698,118 @@ class QuoteTest extends \PHPUnit_Framework_TestCase
         $result = $this->quote->removeAllAddresses();
         $this->assertInstanceOf('Magento\Sales\Model\Quote', $result);
     }
+
+    /**
+     * @expectedException \Magento\Framework\Model\Exception
+     */
+    public function testAddProductException()
+    {
+        $this->quote->addProduct($this->productMock, 'test');
+    }
+
+    public function testAddProductNoCandidates()
+    {
+        $expectedResult = 'test_string';
+        $requestMock = $this->getMock(
+            '\Magento\Framework\Object'
+        );
+        $this->objectFactoryMock->expects($this->once())
+            ->method('create')
+            ->with($this->equalTo(['qty' => 1]))
+            ->will($this->returnValue($requestMock));
+
+        $typeInstanceMock = $this->getMock(
+            'Magento\Catalog\Model\Product\Type\Simple',
+            [
+                'prepareForCartAdvanced'
+            ],
+            [],
+            '',
+            false
+        );
+        $typeInstanceMock->expects($this->once())
+            ->method('prepareForCartAdvanced')
+            ->will($this->returnValue($expectedResult));
+        $this->productMock->expects($this->once())
+            ->method('getTypeInstance')
+            ->will($this->returnValue($typeInstanceMock));
+
+        $result = $this->quote->addProduct($this->productMock, null);
+        $this->assertEquals($expectedResult, $result);
+    }
+
+
+    public function testAddProductItemPreparation()
+    {
+        $itemMock = $this->getMock(
+            '\Magento\Sales\Model\Quote\Item',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $expectedResult = $itemMock;
+        $requestMock = $this->getMock(
+            '\Magento\Framework\Object'
+        );
+        $this->objectFactoryMock->expects($this->once())
+            ->method('create')
+            ->with($this->equalTo(['qty' => 1]))
+            ->will($this->returnValue($requestMock));
+
+        $typeInstanceMock = $this->getMock(
+            'Magento\Catalog\Model\Product\Type\Simple',
+            [
+                'prepareForCartAdvanced'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $productMock = $this->getMock(
+            'Magento\Catalog\Model\Product',
+            [
+                'getParentProductId',
+                'setStickWithinParent',
+                '__wakeup'
+            ],
+            [],
+            '',
+            false
+        );
+
+        $collectionMock = $this->getMock(
+            'Magento\Sales\Model\Resource\Quote\Item\Collection',
+            [],
+            [],
+            '',
+            false
+        );
+
+
+        $itemMock->expects($this->any())
+            ->method('representProduct')
+            ->will($this->returnValue(true));
+
+        $iterator = new \ArrayIterator([$itemMock]);
+        $collectionMock->expects($this->any())
+            ->method('getIterator')
+            ->will($this->returnValue($iterator));
+
+        $this->quoteItemCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($collectionMock));
+
+        $typeInstanceMock->expects($this->once())
+            ->method('prepareForCartAdvanced')
+            ->will($this->returnValue([$productMock]));
+        $this->productMock->expects($this->once())
+            ->method('getTypeInstance')
+            ->will($this->returnValue($typeInstanceMock));
+
+        $result = $this->quote->addProduct($this->productMock, null);
+        $this->assertEquals($expectedResult, $result);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/Rate/ConverterTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/Rate/ConverterTest.php
index f118a6687ddb214f328387ba1e9f7304ede3f793..7ecd71b477b999d1fe4fa6fe466f9a343f2f4689 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/Rate/ConverterTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/Calculation/Rate/ConverterTest.php
@@ -46,14 +46,15 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
         )->disableOriginalConstructor()->setMethods(
             [
                 'getId',
-                'getCountryId',
-                'getRegionId',
+                'getTaxCountryId',
+                'getTaxRegionId',
                 'getTaxPostcode',
                 'getCode',
                 'getRate',
                 'getZipIsRange',
                 'getZipFrom',
                 'getZipTo',
+                'getTitles',
                 '__wakeup',
             ]
         )->getMock();
@@ -61,20 +62,46 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
 
         $taxRateDataOjectBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRateBuilder');
         $zipRangeDataObjectBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\ZipRangeBuilder');
+
+        $directoryRegionModel = $this->getMockBuilder('Magento\Directory\Model\Region')
+            ->disableOriginalConstructor()
+            ->setMethods(['load', 'getCode', '__wakeup'])
+            ->getMock();
+        if ($this->getExpectedValue($valueMap, 'getTaxRegionId') !== null) {
+            $directoryRegionModel->expects($this->once())
+                ->method('load')
+                ->with($this->getExpectedValue($valueMap, 'getTaxRegionId'))
+                ->will($this->returnSelf());
+            $codeForRegion = 'Antarctica';
+            $directoryRegionModel->expects($this->once())
+                ->method('getCode')
+                ->will($this->returnValue($codeForRegion));
+        }
+
+        $taxRateTitleDataObjectBuilder = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\Data\TaxRateTitleBuilder'
+        );
         /** @var  $converter \Magento\Tax\Model\Calculation\Rate\Converter */
         $converter = $this->objectManager->getObject(
             'Magento\Tax\Model\Calculation\Rate\Converter',
             [
                 'taxRateDataObjectBuilder' => $taxRateDataOjectBuilder,
                 'zipRangeDataObjectBuilder' => $zipRangeDataObjectBuilder,
+                'taxRateTitleDataObjectBuilder' => $taxRateTitleDataObjectBuilder,
+                'directoryRegion' => $directoryRegionModel,
             ]
         );
         $taxRateDataObject = $converter->createTaxRateDataObjectFromModel($taxRateModelMock);
         $this->assertEquals($this->getExpectedValue($valueMap, 'getId'), $taxRateDataObject->getId());
         $this->assertEquals($this->getExpectedValue($valueMap, 'getTaxCountryId'), $taxRateDataObject->getCountryId());
         $this->assertEquals($this->getExpectedValue($valueMap, 'getTaxRegionId'), $taxRateDataObject->getRegionId());
+        ///* make sure that 0 is an acceptable value and is converted */
+        $this->assertTrue($this->getExpectedValue($valueMap, 'getTaxRegionId') === $taxRateDataObject->getRegionId());
+        if ($this->getExpectedValue($valueMap, 'getTaxRegionId') !== null) {
+            $this->assertEquals($codeForRegion, $taxRateDataObject->getRegionName());
+        }
         $this->assertEquals($this->getExpectedValue($valueMap, 'getTaxPostcode'), $taxRateDataObject->getPostcode());
-        $this->assertEquals($this->getExpectedValue($valueMap, 'getCode'), $taxRateDataObject->getcode());
+        $this->assertEquals($this->getExpectedValue($valueMap, 'getCode'), $taxRateDataObject->getCode());
         $this->assertEquals($this->getExpectedValue($valueMap, 'getRate'), $taxRateDataObject->getPercentageRate());
         $zipIsRange = $this->getExpectedValue($valueMap, 'getZipIsRange');
         if ($zipIsRange) {
@@ -89,16 +116,42 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
         } else {
             $this->assertNull($taxRateDataObject->getZipRange());
         }
+
+        $titles = $this->getExpectedValue($valueMap, 'getTitles');
+        if ($titles) {
+            $dataObjectTitles = $taxRateDataObject->getTitles();
+            foreach ($titles as $title) {
+                $found = false;
+                foreach ($dataObjectTitles as $dataObjectTitle) {
+                    if (($dataObjectTitle->getValue() === $title->getValue())
+                        && $dataObjectTitle->getStoreId() === $title->getStoreId()) {
+                        $found = true;
+                    }
+                }
+                $this->assertTrue($found, "Did not find title for " . $title->getValue());
+            }
+        }
+        $this->assertEquals(count($titles), count($taxRateDataObject->getTitles()));
     }
 
     public function createTaxRateDataObjectFromModelDataProvider()
     {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $titleModel1 = $this->objectManager->getObject('Magento\Tax\Model\Calculation\Rate\Title');
+        $titleModel1->setValue('tax title');
+        $titleModel1->setStoreId(5);
+
+        $titleModel2 = $this->objectManager->getObject('Magento\Tax\Model\Calculation\Rate\Title');
+        $titleModel2->setValue('tax title 2');
+        $titleModel2->setStoreId(1);
+
         return [
             [
                 [
                     'getId' => '1',
-                    'getCountryId' => 'US',
-                    'getRegionId' => '34',
+                    'getTaxCountryId' => 'US',
+                    'getTaxRegionId' => '34',
                     'getCode' => 'US-CA-*-Rate 1',
                     'getRate' => '8.25',
                     'getZipIsRange' => '1',
@@ -109,11 +162,33 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
             [
                 [
                     'getId' => '1',
-                    'getCountryId' => 'US',
+                    'getTaxCountryId' => 'US',
+                    'getCode' => 'US-CA-*-Rate 1',
+                    'getRate' => '8.25',
+                ],
+            ],
+            [
+                [
+                    'getId' => '1',
+                    'getTaxCountryId' => 'US',
+                    // explicitly 0 to make sure region id is set
+                    'getTaxRegionId' => 0,
                     'getCode' => 'US-CA-*-Rate 1',
                     'getRate' => '8.25',
                 ],
             ],
+            [
+                [
+                    'getId' => '1',
+                    'getTaxCountryId' => 'US',
+                    'getTaxRegionId' => '34',
+                    'getCode' => 'US-CA-*-Rate 1',
+                    'getRate' => '8.25',
+                    'getTitles' => [
+                        $titleModel1
+                    ]
+                ],
+            ],
         ];
     }
 
@@ -251,4 +326,62 @@ class ConverterTest extends \PHPUnit_Framework_TestCase
             $mock->expects($this->any())->method($method)->will($this->returnValue($value));
         }
     }
+
+    /**
+     * @param array $data
+     * @dataProvider createTaxRateTitleDataProvider
+     */
+    public function testCreateTitlesFromServiceObject($data)
+    {
+        $taxRateBuilder = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\Data\TaxRateBuilder'
+        );
+
+        $taxRate = $taxRateBuilder->setTitles($data)->create();
+
+        /** @var  $converter \Magento\Tax\Model\Calculation\Rate\Converter */
+        $converter = $this->objectManager->getObject(
+            'Magento\Tax\Model\Calculation\Rate\Converter'
+        );
+
+        $titles = $converter->createTitleArrayFromServiceObject($taxRate);
+        foreach ($data as $expectedTitle) {
+            $storeId = $expectedTitle->getStoreId();
+            $this->assertTrue(isset($titles[$storeId]), "Title for store id {$storeId} was not set.");
+            $this->assertEquals($expectedTitle->getValue(), $titles[$storeId]);
+        }
+    }
+
+    public function createTaxRateTitleDataProvider()
+    {
+        $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
+
+        $titleBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRateTitleBuilder');
+        $titleBuilder->setValue('tax title');
+        $titleBuilder->setStoreId(5);
+
+        $title1 = $titleBuilder->create();
+
+        $titleBuilder->setValue('tax title 2');
+        $titleBuilder->setStoreId(1);
+
+        $title2 = $titleBuilder->create();
+
+        return [
+            'no titles' => [
+                []
+            ],
+            '1 title' => [
+                [
+                    $title1
+                ]
+            ],
+            '2 title2' => [
+                [
+                  $title1,
+                  $title2,
+                ]
+            ]
+        ];
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Model/ClassModelRegistryTest.php b/dev/tests/unit/testsuite/Magento/Tax/Model/ClassModelRegistryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..325522d66fdf67588c6533646983e7f51a2b1baf
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Tax/Model/ClassModelRegistryTest.php
@@ -0,0 +1,106 @@
+<?php
+/**
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+
+namespace Magento\Tax\Model;
+
+use Magento\TestFramework\Helper\ObjectManager;
+
+/**
+ * Test for TaxRuleRegistry
+ */
+class ClassModelRegistryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Tax\Model\ClassModelRegistry
+     */
+    private $taxRuleRegistry;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Model\ClassModelFactory
+     */
+    private $classModelFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Model\ClassModel
+     */
+    private $classModelMock;
+
+    const CLASS_MODEL = 1;
+
+    public function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->classModelFactoryMock = $this->getMockBuilder('Magento\Tax\Model\ClassModelFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->taxRuleRegistry = $objectManager->getObject(
+            'Magento\Tax\Model\ClassModelRegistry',
+            ['taxClassModelFactory' => $this->classModelFactoryMock]
+        );
+        $this->classModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->classModelFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($this->classModelMock));
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
+     */
+    public function testUpdateTaxClassNotExistingEntity()
+    {
+        $taxClassId = 1;
+
+        $this->classModelMock
+            ->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue(null));
+
+        $this->classModelMock->expects($this->once())
+            ->method('load')
+            ->with($taxClassId)
+            ->will($this->returnValue($this->classModelMock));
+
+        $this->taxRuleRegistry->retrieve($taxClassId);
+    }
+
+    public function testGetTaxClass()
+    {
+        $taxClassId = 1;
+
+        $this->classModelMock
+            ->expects($this->exactly(2))
+            ->method('getId')
+            ->will($this->returnValue($taxClassId));
+
+        $this->classModelMock->expects($this->once())
+            ->method('load')
+            ->with($taxClassId)
+            ->will($this->returnValue($this->classModelMock));
+
+        $this->assertEquals($this->classModelMock, $this->taxRuleRegistry->retrieve($taxClassId));
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php
index f878e4211c59156f6ce422986e724e4dfcb7356f..9e9e3bd4c9aa5c05c912d7816a95bd77daf1ff7c 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Pricing/Price/Plugin/AttributePriceTest.php
@@ -160,6 +160,7 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase
             'product' => $this->productMock,
             'defaultTax' => 99.10,
             'currentTax' => 99.10,
+            'customerId' => 1,
             'includeTax' => true,
             'showIncludeTax' => true,
             'showBothPrices' => true
@@ -168,7 +169,8 @@ class AttributePriceTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($expected, $this->plugin->afterPrepareAdjustmentConfig($this->attributePriceMock, [
             'product' => $this->productMock,
             'defaultTax' => 0,
-            'currentTax' => 0
+            'currentTax' => 0,
+            'customerId' => 1,
         ]));
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
index 209e47f1dea9e48a0fe8e0bf2e1df47267be7fd5..654619dbf083b25af70704eabcbff26e90973dc3 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxClassServiceTest.php
@@ -30,6 +30,8 @@ use Magento\Tax\Service\V1\Data\TaxClassBuilder;
 
 /**
  * Test for \Magento\Tax\Service\V1\TaxClassService
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  */
 class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
 {
@@ -39,14 +41,14 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     private $taxClassCollectionFactory;
 
     /**
-     * @var \Magento\Tax\Service\V1\Data\SearchResultsBuilder|\PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Tax\Service\V1\Data\TaxClassSearchResultsBuilder|\PHPUnit_Framework_MockObject_MockObject
      */
     private $searchResultBuilder;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Tax\Model\ClassModelFactory
      */
-    private $taxClassModelFactoryMock;
+    private $classModelRegistryMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Tax\Model\ClassModel
@@ -77,9 +79,9 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     {
         $this->objectManager = new \Magento\TestFramework\Helper\ObjectManager($this);
 
-        $this->taxClassModelFactoryMock = $this->getMockBuilder('Magento\Tax\Model\ClassModelFactory')
+        $this->classModelRegistryMock = $this->getMockBuilder('Magento\Tax\Model\ClassModelRegistry')
             ->disableOriginalConstructor()
-            ->setMethods(['create'])
+            ->setMethods(['retrieve', 'registerTaxClass'])
             ->getMock();
 
         $this->taxClassModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel')
@@ -87,8 +89,8 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
             ->setMethods(['load', 'getId', 'delete', 'save', 'getClassType', '__wakeup'])
             ->getMock();
 
-        $this->taxClassModelFactoryMock->expects($this->any())
-            ->method('create')
+        $this->classModelRegistryMock->expects($this->any())
+            ->method('retrieve')
             ->will($this->returnValue($this->taxClassModelMock));
 
         $this->taxClassBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxClassBuilder');
@@ -98,10 +100,10 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
 
     public function testCreateTaxClass()
     {
-        $taxClassId = 1;;
+        $taxClassId = 1;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
@@ -130,7 +132,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     public function testCreateTaxClassException()
     {
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
@@ -181,74 +183,19 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         }
     }
 
-    public function testGetTaxClass()
-    {
-        $taxClassId = 1;
-
-        $taxClassDataObjectMock = $this->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClass')
-            ->disableOriginalConstructor()
-            ->getMock();
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
-        $this->converterMock->expects($this->once())
-            ->method('createTaxClassData')
-            ->with($this->taxClassModelMock)
-            ->will($this->returnValue($taxClassDataObjectMock));
-
-        $this->assertEquals($taxClassDataObjectMock, $this->taxClassService->getTaxClass($taxClassId));
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     * @expectedExceptionMessage No such entity with class_id = -9999
-     */
-    public function testGetTaxClassWithNoSuchEntityException()
-    {
-        $taxClassId = -9999;
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue(null));
-
-        $this->taxClassService->getTaxClass($taxClassId);
-    }
-
     public function testUpdateTaxClassSuccess()
     {
         $taxClassId = 1;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
-        $this->taxClassModelMock
-            ->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
         $this->taxClassModelMock
             ->expects($this->exactly(2))
             ->method('getClassType')
-            ->will($this->returnValue(TaxClass::TYPE_PRODUCT));
+            ->will($this->returnValue(TaxClassServiceInterface::TYPE_PRODUCT));
 
         $this->taxClassModelMock
             ->expects($this->once())
@@ -272,7 +219,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassId = 1;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->create();
 
         $this->taxClassService->updateTaxClass($taxClassId, $taxClassSample);
@@ -334,35 +281,10 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassId = null;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
-            ->setClassName('Wholesale product')
-            ->create();
-
-        $this->taxClassService->updateTaxClass($taxClassId, $taxClassSample);
-    }
-
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     */
-    public function testUpdateTaxClassNotExistingEntity()
-    {
-        $taxClassId = 1;
-
-        $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
-        $this->taxClassModelMock
-            ->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue(null));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
         $this->taxClassService->updateTaxClass($taxClassId, $taxClassSample);
     }
 
@@ -375,24 +297,14 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassId = 1;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
-        $this->taxClassModelMock
-            ->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
         $this->taxClassModelMock
             ->expects($this->once())
             ->method('getClassType')
-            ->will($this->returnValue(TaxClass::TYPE_PRODUCT));
+            ->will($this->returnValue(TaxClassServiceInterface::TYPE_PRODUCT));
 
         $convertedTaxClassModelMock = $this->getMockBuilder('Magento\Tax\Model\ClassModel')
             ->disableOriginalConstructor()
@@ -402,7 +314,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $convertedTaxClassModelMock
             ->expects($this->once())
             ->method('getClassType')
-            ->will($this->returnValue(TaxClass::TYPE_CUSTOMER));
+            ->will($this->returnValue(TaxClassServiceInterface::TYPE_CUSTOMER));
 
         $this->converterMock
             ->expects($this->once())
@@ -418,24 +330,14 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
         $taxClassId = 1;
 
         $taxClassSample = $this->taxClassBuilder
-            ->setClassType(TaxClass::TYPE_PRODUCT)
+            ->setClassType(TaxClassServiceInterface::TYPE_PRODUCT)
             ->setClassName('Wholesale product')
             ->create();
 
-        $this->taxClassModelMock
-            ->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
         $this->taxClassModelMock
             ->expects($this->exactly(2))
             ->method('getClassType')
-            ->will($this->returnValue(TaxClass::TYPE_PRODUCT));
+            ->will($this->returnValue(TaxClassServiceInterface::TYPE_PRODUCT));
 
         $this->converterMock
             ->expects($this->once())
@@ -455,15 +357,6 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     {
         $taxClassId = 1;
 
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
         $this->taxClassModelMock->expects($this->once())
             ->method('delete')
             ->will($this->throwException(new \Exception()));
@@ -475,40 +368,12 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
     {
         $taxClassId = 1;
 
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue($taxClassId));
-
         $this->taxClassModelMock->expects($this->once())
             ->method('delete');
 
         $this->assertTrue($this->taxClassService->deleteTaxClass($taxClassId));
     }
 
-    /**
-     * @expectedException \Magento\Framework\Exception\NoSuchEntityException
-     */
-    public function testDeleteNonExistentModel()
-    {
-        $taxClassId = 1;
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('load')
-            ->with($taxClassId)
-            ->will($this->returnValue($this->taxClassModelMock));
-
-        $this->taxClassModelMock->expects($this->once())
-            ->method('getId')
-            ->will($this->returnValue(null));
-
-        $this->taxClassService->deleteTaxClass($taxClassId);
-    }
-
     public function testSearch()
     {
         $collectionSize = 3;
@@ -565,8 +430,9 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->searchResultBuilder = $this
-            ->getMockBuilder('Magento\Tax\Service\V1\Data\SearchResultsBuilder')
+            ->getMockBuilder('Magento\Tax\Service\V1\Data\TaxClassSearchResultsBuilder')
             ->disableOriginalConstructor()
+            ->setMethods(['setSearchCriteria', 'setItems', 'setTotalCount', 'create'])
             ->getMock();
 
         $this->converterMock = $this->getMockBuilder('Magento\Tax\Model\Converter')
@@ -577,7 +443,7 @@ class TaxClassServiceTest extends \PHPUnit_Framework_TestCase
             'Magento\Tax\Service\V1\TaxClassService',
             [
                 'taxClassCollectionFactory' => $this->taxClassCollectionFactory,
-                'taxClassModelFactory' => $this->taxClassModelFactoryMock,
+                'classModelRegistry' => $this->classModelRegistryMock,
                 'searchResultsBuilder' => $this->searchResultBuilder,
                 'converter' => $this->converterMock
             ]
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
index af61c181098104dcf4e8f3404cb3a954b36e6d18..66e4acd2ff73cd28af59c3e4df4a76c4520b4ae6 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRateServiceTest.php
@@ -27,9 +27,18 @@ use Magento\Framework\Exception\NoSuchEntityException;
 use Magento\Tax\Model\Calculation\Rate as RateModel;
 use Magento\Tax\Service\V1\Data\TaxRate;
 use Magento\TestFramework\Helper\ObjectManager;
+use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
+use Magento\Tax\Model\Calculation\RateFactory;
 
+/**
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
 class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
 {
+    /** Sample values for testing */
+
+    const REGION_ID = 42;
+
     /**
      * @var TaxRateServiceInterface
      */
@@ -55,6 +64,26 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
      */
     private $objectManager;
 
+    /**
+     * @var SearchCriteriaBuilder
+     */
+    protected $searchCriteriaBuilder;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | RateFactory
+     */
+    private $rateFactoryMock;
+
+    /**
+     * @var Data\TaxRateSearchResultsBuilder
+     */
+    private $taxRateSearchResultsBuilder;
+
+    /**
+     * @var  \Magento\Tax\Service\V1\Data\TaxRateBuilder'
+     */
+    private $taxRateBuilder;
+
     public function setUp()
     {
         $this->objectManager = new ObjectManager($this);
@@ -67,13 +96,26 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
         $this->rateModelMock = $this->getMockBuilder('Magento\Tax\Model\Calculation\Rate')
             ->disableOriginalConstructor()
             ->getMock();
-        $this->taxRateService = $this->objectManager->getObject(
-            'Magento\Tax\Service\V1\TaxRateService',
-            [
-                'rateRegistry' => $this->rateRegistryMock,
-                'converter' => $this->converterMock,
-            ]
+        $this->rateFactoryMock = $this->getMockBuilder('Magento\Tax\Model\Calculation\RateFactory')
+        ->disableOriginalConstructor()
+        ->getMock();
+        $this->taxRateSearchResultsBuilder = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\Data\TaxRateSearchResultsBuilder'
+        );
+        $filterGroupBuilder = $this->objectManager
+            ->getObject('Magento\Framework\Service\V1\Data\Search\FilterGroupBuilder');
+        /** @var SearchCriteriaBuilder $searchBuilder */
+        $this->searchCriteriaBuilder = $this->objectManager->getObject(
+            'Magento\Framework\Service\V1\Data\SearchCriteriaBuilder',
+            ['filterGroupBuilder' => $filterGroupBuilder]
+        );
+
+        $zipRangeBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\ZipRangeBuilder');
+        $this->taxRateBuilder = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\Data\TaxRateBuilder',
+            ['zipRangeBuilder' => $zipRangeBuilder]
         );
+        $this->createService();
     }
 
     public function testCreateTaxRate()
@@ -86,20 +128,14 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
             'zip_range' => ['from' => 78765, 'to' => 78780]
         ];
 
-        $zipRangeBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\ZipRangeBuilder');
-        $taxRateBuilder = $this->objectManager->getObject(
-            'Magento\Tax\Service\V1\Data\TaxRateBuilder',
-            ['zipRangeBuilder' => $zipRangeBuilder]
-        );
-
-        $taxRateDataObject = $taxRateBuilder->populateWithArray($taxData)->create();
+        $taxRateDataObject =   $this->taxRateBuilder->populateWithArray($taxData)->create();
         $this->rateModelMock->expects($this->once())
             ->method('save')
             ->will($this->returnValue($this->rateModelMock));
         $this->converterMock->expects($this->once())
             ->method('createTaxRateModel')
             ->will($this->returnValue($this->rateModelMock));
-        $taxRate = $taxRateBuilder->populate($taxRateDataObject)->setPostcode('78765-78780')->create();
+        $taxRate =   $this->taxRateBuilder->populate($taxRateDataObject)->setPostcode('78765-78780')->create();
         $this->converterMock->expects($this->once())
             ->method('createTaxRateDataObjectFromModel')
             ->will($this->returnValue($taxRate));
@@ -124,12 +160,7 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
             'code' => 'US-CA-*-Rate',
             'zip_range' => ['from' => 78765, 'to' => 78780]
         ];
-        $zipRangeBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\ZipRangeBuilder');
-        $taxRateBuilder = $this->objectManager->getObject(
-            'Magento\Tax\Service\V1\Data\TaxRateBuilder',
-            ['zipRangeBuilder' => $zipRangeBuilder]
-        );
-        $taxRateDataObject = $taxRateBuilder->populateWithArray($taxData)->create();
+        $taxRateDataObject = $this->taxRateBuilder->populateWithArray($taxData)->create();
         $this->taxRateService->createTaxRate($taxRateDataObject);
     }
 
@@ -145,12 +176,8 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
             'code' => 'US-CA-*-Rate',
             'zip_range' => ['from' => 78765, 'to' => 78780]
         ];
-        $zipRangeBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\ZipRangeBuilder');
-        $taxRateBuilder = $this->objectManager->getObject(
-            'Magento\Tax\Service\V1\Data\TaxRateBuilder',
-            ['zipRangeBuilder' => $zipRangeBuilder]
-        );
-        $taxRateDataObject = $taxRateBuilder->populateWithArray($taxData)->create();
+
+        $taxRateDataObject =   $this->taxRateBuilder->populateWithArray($taxData)->create();
         $this->rateModelMock->expects($this->once())
             ->method('save')
             ->will($this->throwException(new \Magento\Framework\Model\Exception()));
@@ -194,8 +221,7 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
 
     public function testUpdateTaxRate()
     {
-        $taxRateBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRateBuilder');
-        $taxRate = $taxRateBuilder
+        $taxRate = $this->taxRateBuilder
             ->setId(2)
             ->setCode('Rate-Code')
             ->setCountryId('US')
@@ -219,8 +245,7 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
      */
     public function testUpdateTaxRateNoId()
     {
-        $taxRateBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRateBuilder');
-        $taxRate = $taxRateBuilder
+        $taxRate = $this->taxRateBuilder
             ->setCode('Rate-Code')
             ->setCountryId('US')
             ->setPercentageRate(0.1)
@@ -240,11 +265,9 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
      */
     public function testUpdateTaxRateMissingRequiredInfo()
     {
-        $taxRateBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRateBuilder');
-        $taxRate = $taxRateBuilder
+        $taxRate = $this->taxRateBuilder
             ->setId(2)
             ->setCode('Rate-Code')
-            ->setCountryId('US')
             ->setPercentageRate(0.1)
             ->setRegionId('TX')
             ->create();
@@ -292,4 +315,124 @@ class TaxRateServiceTest extends \PHPUnit_Framework_TestCase
             ->will($this->throwException(new \Exception('Bad error occurred')));
         $this->taxRateService->deleteTaxRate(1);
     }
+
+    public function testSearchTaxRateEmpty()
+    {
+        $collectionMock = $this->getMockBuilder('Magento\Tax\Model\Resource\Calculation\Rate\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getSize', 'load', 'joinRegionTable'])
+            ->getMock();
+
+        $this->mockReturnValue($collectionMock, ['getSize' => 0]);
+        $this->rateFactoryMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->will($this->returnValue($this->rateModelMock));
+        $this->mockReturnValue(
+            $this->rateModelMock,
+            [
+                'load' => $this->returnSelf(),
+                'getCollection' => $collectionMock
+            ]
+        );
+
+        $filterBuilder = $this->objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
+        $filter = $filterBuilder->setField(TaxRate::KEY_REGION_ID)->setValue(self::REGION_ID)->create();
+        $this->searchCriteriaBuilder->addFilter([$filter]);
+
+        $this->createService();
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchCriteria->getSortOrders();
+        $searchResults = $this->taxRateService->searchTaxRates($searchCriteria);
+        $items = $searchResults->getItems();
+        $this->assertNotNull($searchResults);
+        $this->assertSame($searchCriteria, $searchResults->getSearchCriteria());
+        $this->assertEquals(0, $searchResults->getTotalCount());
+        $this->assertNotNull($items);
+        $this->assertTrue(empty($items));
+    }
+
+    public function testSearchTaxRate()
+    {
+        $collectionMock = $this->getMockBuilder('Magento\Tax\Model\Resource\Calculation\Rate\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['addFieldToFilter', 'getSize', 'load', 'getIterator', 'joinRegionTable'])
+            ->getMock();
+
+        $this->mockReturnValue(
+            $collectionMock,
+            [
+                'getSize' => 1,
+                'getIterator' => new \ArrayIterator([$this->rateModelMock])
+            ]
+        );
+
+        $this->rateFactoryMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->will($this->returnValue($this->rateModelMock));
+
+        $this->mockReturnValue(
+            $this->rateModelMock,
+            [
+                'load' => $this->returnSelf(),
+                'getCollection' => $collectionMock,
+            ]
+        );
+
+        $taxRate = $this->taxRateBuilder
+            ->setId(2)
+            ->setCode('Rate-Code')
+            ->setCountryId('US')
+            ->setPercentageRate(0.1)
+            ->setPostcode('55555')
+            ->setRegionId(self::REGION_ID)
+            ->create();
+        $this->converterMock->expects($this->once())
+            ->method('createTaxRateDataObjectFromModel')
+            ->with($this->rateModelMock)
+            ->will($this->returnValue($taxRate));
+
+        $filterBuilder = $this->objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
+        $filter = $filterBuilder->setField(TaxRate::KEY_REGION_ID)->setValue(self::REGION_ID)->create();
+        $this->searchCriteriaBuilder
+            ->addFilter([$filter])
+            ->addSortOrder('id', \Magento\Framework\Service\V1\Data\SearchCriteria::SORT_ASC);
+
+        $this->createService();
+        $searchCriteria = $this->searchCriteriaBuilder->create();
+        $searchResults = $this->taxRateService->searchTaxRates($searchCriteria);
+        $items = $searchResults->getItems();
+        $this->assertNotNull($searchResults);
+        $this->assertSame($searchCriteria, $searchResults->getSearchCriteria());
+        $this->assertEquals(1, $searchResults->getTotalCount());
+        $this->assertNotNull($items);
+        $this->assertFalse(empty($items));
+        $this->assertEquals(self::REGION_ID, $items[0]->getRegionId());
+    }
+
+    /**
+     * @param \PHPUnit_Framework_MockObject_MockObject $mock
+     * @param array $valueMap
+     */
+    private function mockReturnValue($mock, $valueMap)
+    {
+        foreach ($valueMap as $method => $value) {
+            $mock->expects($this->any())->method($method)->will($this->returnValue($value));
+        }
+    }
+
+    /**
+     * create taxRateService
+     */
+    private function createService()
+    {
+        $this->taxRateService = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\TaxRateService',
+            [
+                'rateFactory' => $this->rateFactoryMock,
+                'rateRegistry' => $this->rateRegistryMock,
+                'converter' => $this->converterMock,
+                'taxRateSearchResultsBuilder' => $this->taxRateSearchResultsBuilder
+            ]
+        );
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
index 5426cf1d65fb5099963a94d6785396cbd1cc6ed2..8e782df621e273e74f0a27e3e57ff74b52ba78fd 100644
--- a/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
+++ b/dev/tests/unit/testsuite/Magento/Tax/Service/V1/TaxRuleServiceTest.php
@@ -26,6 +26,7 @@ namespace Magento\Tax\Service\V1;
 use Magento\Framework\Exception\ErrorMessage;
 use Magento\Framework\Exception\InputException;
 use Magento\Framework\Exception\NoSuchEntityException;
+use Magento\Framework\Model\Resource\Iterator;
 use Magento\TestFramework\Helper\ObjectManager;
 
 class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
@@ -50,6 +51,11 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
      */
     private $ruleModelMock;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject | \Magento\Tax\Model\Calculation\RuleFactory
+     */
+    private $taxRuleModelFactoryMock;
+
     /**
      * @var ObjectManager
      */
@@ -67,10 +73,24 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
         $this->ruleModelMock = $this->getMockBuilder('Magento\Tax\Model\Calculation\Rule')
             ->disableOriginalConstructor()
             ->getMock();
-        $this->taxRuleService = $this->objectManager->getObject('Magento\Tax\Service\V1\TaxRuleService',
+        $this->taxRuleModelFactoryMock = $this->getMockBuilder('\Magento\Tax\Model\Calculation\RuleFactory')
+            ->disableOriginalConstructor()
+            ->setMethods(['create'])
+            ->getMock();
+        $this->taxRuleModelFactoryMock->expects($this->any())
+            ->method('create')
+            ->will($this->returnValue($this->ruleModelMock));
+
+        $taxRuleResultsBuilder = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder'
+        );
+        $this->taxRuleService = $this->objectManager->getObject(
+            'Magento\Tax\Service\V1\TaxRuleService',
             [
-                'taxRuleRegistry' => $this->ruleRegistryMock,
-                'converter' => $this->converterMock,
+                'taxRuleRegistry'     => $this->ruleRegistryMock,
+                'converter'           => $this->converterMock,
+                'taxRuleModelFactory' => $this->taxRuleModelFactoryMock,
+                'taxRuleSearchResultsBuilder' => $taxRuleResultsBuilder
             ]
         );
     }
@@ -270,8 +290,6 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
             'empty fields' => [
                 [],
                 [
-                    'sort_order is a required field.',
-                    'priority is a required field.',
                     'code is a required field.',
                     'customer_tax_class_ids is a required field.',
                     'product_tax_class_ids is a required field.',
@@ -322,4 +340,105 @@ class TaxRuleServiceTest extends \PHPUnit_Framework_TestCase
         $this->taxRuleService->createTaxRule($taxRule);
     }
 
+    public function testSearchTaxRulesEmptyResult()
+    {
+        /** @var \PHPUnit_Framework_MockObject_MockObject |
+         * \Magento\Framework\Service\V1\Data\SearchCriteria $mockSearchCriteria */
+        $mockSearchCriteria = $this->getMockBuilder('\Magento\Framework\Service\V1\Data\SearchCriteria')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $mockSearchCriteria->expects($this->once())
+            ->method('getFilterGroups')
+            ->will($this->returnValue([]));
+
+        $mockCollection = $this->getMockBuilder('\Magento\Tax\Model\Resource\Calculation\Rule\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $mockCollection->expects($this->once())
+            ->method('getIterator')
+            ->will($this->returnValue(new \ArrayIterator([])));
+
+        $this->ruleModelMock->expects($this->once())
+            ->method('getCollection')
+            ->will($this->returnValue($mockCollection));
+
+        $mockCollection->expects($this->once())
+            ->method('getSize')
+            ->will($this->returnValue(0));
+
+        $taxSearchResults = $this->taxRuleService->searchTaxRules($mockSearchCriteria);
+
+        $this->assertNotNull($taxSearchResults);
+        $this->assertSame($mockSearchCriteria, $taxSearchResults->getSearchCriteria());
+        $this->assertSame(0, $taxSearchResults->getTotalCount());
+        $items = $taxSearchResults->getItems();
+        $this->assertNotNull($items);
+        $this->assertTrue(empty($items));
+    }
+
+    public function testSearchTaxRulesSingleResult()
+    {
+        /** @var \PHPUnit_Framework_MockObject_MockObject |
+         * \Magento\Tax\Model\Resource\Calculation\Rule\Collection $mockCollection */
+        $mockCollection = $this->getMockBuilder('\Magento\Tax\Model\Resource\Calculation\Rule\Collection')
+            ->disableOriginalConstructor()
+            ->setMethods(['__wakeup', 'getItems', 'getSize', 'addFieldToFilter', '_beforeLoad', 'getIterator'])
+            ->getMock();
+        /** @var \Magento\Tax\Service\V1\Data\TaxRuleBuilder $taxRuleBuilder */
+        $taxRuleBuilder = $this->objectManager->getObject('Magento\Tax\Service\V1\Data\TaxRuleBuilder');
+        /** @var \Magento\Tax\Service\V1\Data\TaxRule $taxRule */
+        $taxRule = $taxRuleBuilder->create();
+
+        $taxRuleModel = $this->getMockBuilder('Magento\Tax\Model\Calculation\Rule')
+            ->disableOriginalConstructor()->getMock();
+        $mockCollection->expects($this->once())
+            ->method('getIterator')
+            ->will($this->returnValue(new \ArrayIterator([$taxRuleModel])));
+        $mockCollection->expects($this->once())
+            ->method('getSize')
+            ->will($this->returnValue(1));
+
+        $filterBuilder = $this->objectManager->getObject('\Magento\Framework\Service\V1\Data\FilterBuilder');
+        $filter = $filterBuilder->setField('code')->setValue('code')->setConditionType('eq')->create();
+
+        $filterGroupBuilder = $this->objectManager
+            ->getObject('Magento\Framework\Service\V1\Data\Search\FilterGroupBuilder');
+        /** @var \Magento\Framework\Service\V1\Data\SearchCriteriaBuilder $searchCriteriaBuilder */
+        $searchCriteriaBuilder = $this->objectManager->getObject(
+            'Magento\Framework\Service\V1\Data\SearchCriteriaBuilder',
+            ['filterGroupBuilder' => $filterGroupBuilder]
+        );
+        $searchCriteria = $searchCriteriaBuilder
+            ->addFilter([$filter])
+            ->addSortOrder('id', \Magento\Framework\Service\V1\Data\SearchCriteria::SORT_ASC)
+            ->create();
+
+        /** @var \Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder $searchResultsBuilder */
+        $searchResultsBuilder = $this->objectManager->getObject(
+            '\Magento\Tax\Service\V1\Data\TaxRuleSearchResultsBuilder'
+        );
+        $expectedResults = $searchResultsBuilder->setSearchCriteria($searchCriteria)
+            ->setItems([$taxRule])
+            ->setTotalCount(1)
+            ->create();
+
+        $this->ruleModelMock->expects($this->once())
+            ->method('getCollection')
+            ->will($this->returnValue($mockCollection));
+
+        $this->converterMock->expects($this->once())
+            ->method('createTaxRuleDataObjectFromModel')->with($taxRuleModel)
+            ->will($this->returnValue($taxRule));
+
+        $actualResults = $this->taxRuleService->searchTaxRules($searchCriteria);
+
+        $this->assertNotNull($actualResults);
+        $this->assertSame($searchCriteria, $actualResults->getSearchCriteria());
+        $this->assertSame($expectedResults->getSearchCriteria(), $actualResults->getSearchCriteria());
+        $this->assertSame($expectedResults->getTotalCount(), $actualResults->getTotalCount());
+        $this->assertEquals($expectedResults->getItems(), $actualResults->getItems());
+        $this->assertSame($taxRule, $actualResults->getItems()[0]);
+    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..84b5b112c167cc2d4ba15c54510f05cd18aa64ce
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/IndexTest.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class IndexTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeTest
+{
+    /**
+     * @var string
+     */
+    protected $name = 'Index';
+
+    public function testIndexAction()
+    {
+        $menuModel = $this->getMock(
+            'Magento\Backend\Model\Menu',
+            [],
+            [$this->getMock('Magento\Framework\Logger', [], [], '', false)]
+        );
+        $menuModel->expects($this->once())
+            ->method('getParentItems')
+            ->with($this->equalTo('Magento_Theme::system_design_theme'))
+            ->will($this->returnValue(array()));
+
+        $menuBlock = $this->getMock('\Magento\Backend\Block\Menu', array(), array(), '', false);
+        $menuBlock->expects($this->once())
+            ->method('getMenuModel')
+            ->will($this->returnValue($menuModel));
+
+        $layout = $this->getMock('\Magento\Framework\View\LayoutInterface', array(), array(), '', false);
+        $layout->expects($this->any())
+            ->method('getBlock')
+            ->with($this->equalTo('menu'))
+            ->will($this->returnValue($menuBlock));
+
+        $this->view->expects($this->once())
+            ->method('getLayout')
+            ->will($this->returnValue($layout));
+
+        $this->eventManager->expects($this->once())
+            ->method('dispatch')
+            ->with($this->equalTo('theme_registration_from_filesystem'))
+            ->will($this->returnValue(null));
+        $this->_model->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c65499b8c3c760995baa3ae8215ca3b7a1801c3
--- /dev/null
+++ b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/Theme/SaveTest.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Theme\Controller\Adminhtml\System\Design\Theme;
+
+class SaveTest extends \Magento\Theme\Controller\Adminhtml\System\Design\ThemeTest
+{
+    /**
+     * @var string
+     */
+    protected $name = 'Save';
+
+    /**
+     * @covers \Magento\Theme\Controller\Adminhtml\System\Design\Theme::saveAction
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testSaveAction()
+    {
+        $themeData = array('theme_id' => 123);
+        $customCssContent = 'custom css content';
+        $jsRemovedFiles = array(3, 4);
+        $jsOrder = array(1 => '1', 2 => 'test');
+
+        $this->_request->expects(
+            $this->at(0)
+        )->method(
+                'getParam'
+            )->with(
+                'back',
+                false
+            )->will(
+                $this->returnValue(true)
+            );
+
+        $this->_request->expects(
+            $this->at(1)
+        )->method(
+                'getParam'
+            )->with(
+                'theme'
+            )->will(
+                $this->returnValue($themeData)
+            );
+        $this->_request->expects(
+            $this->at(2)
+        )->method(
+                'getParam'
+            )->with(
+                'custom_css_content'
+            )->will(
+                $this->returnValue($customCssContent)
+            );
+        $this->_request->expects(
+            $this->at(3)
+        )->method(
+                'getParam'
+            )->with(
+                'js_removed_files'
+            )->will(
+                $this->returnValue($jsRemovedFiles)
+            );
+        $this->_request->expects(
+            $this->at(4)
+        )->method(
+                'getParam'
+            )->with(
+                'js_order'
+            )->will(
+                $this->returnValue($jsOrder)
+            );
+        $this->_request->expects($this->once(5))->method('getPost')->will($this->returnValue(true));
+
+        $themeMock = $this->getMock(
+            'Magento\Core\Model\Theme',
+            array('save', 'load', 'setCustomization', 'getThemeImage', '__wakeup'),
+            array(),
+            '',
+            false
+        );
+
+        $themeImage = $this->getMock('Magento\Core\Model\Theme\Image', array(), array(), '', false);
+        $themeMock->expects($this->any())->method('getThemeImage')->will($this->returnValue($themeImage));
+
+        $themeFactory = $this->getMock(
+            'Magento\Framework\View\Design\Theme\FlyweightFactory',
+            array('create'),
+            array(),
+            '',
+            false
+        );
+        $themeFactory->expects($this->once())->method('create')->will($this->returnValue($themeMock));
+
+        $this->_objectManagerMock->expects(
+            $this->at(0)
+        )->method(
+                'get'
+            )->with(
+                'Magento\Framework\View\Design\Theme\FlyweightFactory'
+            )->will(
+                $this->returnValue($themeFactory)
+            );
+
+        $this->_objectManagerMock->expects(
+            $this->at(1)
+        )->method(
+                'get'
+            )->with(
+                'Magento\Theme\Model\Theme\Customization\File\CustomCss'
+            )->will(
+                $this->returnValue(null)
+            );
+
+        $this->_objectManagerMock->expects(
+            $this->at(2)
+        )->method(
+                'create'
+            )->with(
+                'Magento\Theme\Model\Theme\SingleFile'
+            )->will(
+                $this->returnValue(null)
+            );
+
+        $this->_model->execute();
+    }
+}
diff --git a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/ThemeTest.php b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/ThemeTest.php
index 49b3086a4591df5ce36493dd3e168b4c6eeb7f49..150f1efe5ebe0ef647c934d8fcb7c188d7cf354f 100644
--- a/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/ThemeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Theme/Controller/Adminhtml/System/Design/ThemeTest.php
@@ -27,8 +27,13 @@
  */
 namespace Magento\Theme\Controller\Adminhtml\System\Design;
 
-class ThemeTest extends \PHPUnit_Framework_TestCase
+abstract class ThemeTest extends \PHPUnit_Framework_TestCase
 {
+    /**
+     * @var string
+     */
+    protected $name = '';
+
     /**
      * @var \Magento\Theme\Controller\Adminhtml\System\Design\Theme
      */
@@ -64,7 +69,7 @@ class ThemeTest extends \PHPUnit_Framework_TestCase
 
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
         $this->_model = $helper->getObject(
-            'Magento\Theme\Controller\Adminhtml\System\Design\Theme',
+            'Magento\Theme\Controller\Adminhtml\System\Design\Theme\\' . $this->name,
             array(
                 'request' => $this->_request,
                 'objectManager' => $this->_objectManagerMock,
@@ -74,147 +79,4 @@ class ThemeTest extends \PHPUnit_Framework_TestCase
             )
         );
     }
-
-    /**
-     * @covers \Magento\Theme\Controller\Adminhtml\System\Design\Theme::saveAction
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    public function testSaveAction()
-    {
-        $themeData = array('theme_id' => 123);
-        $customCssContent = 'custom css content';
-        $jsRemovedFiles = array(3, 4);
-        $jsOrder = array(1 => '1', 2 => 'test');
-
-        $this->_request->expects(
-            $this->at(0)
-        )->method(
-                'getParam'
-            )->with(
-                'back',
-                false
-            )->will(
-                $this->returnValue(true)
-            );
-
-        $this->_request->expects(
-            $this->at(1)
-        )->method(
-                'getParam'
-            )->with(
-                'theme'
-            )->will(
-                $this->returnValue($themeData)
-            );
-        $this->_request->expects(
-            $this->at(2)
-        )->method(
-                'getParam'
-            )->with(
-                'custom_css_content'
-            )->will(
-                $this->returnValue($customCssContent)
-            );
-        $this->_request->expects(
-            $this->at(3)
-        )->method(
-                'getParam'
-            )->with(
-                'js_removed_files'
-            )->will(
-                $this->returnValue($jsRemovedFiles)
-            );
-        $this->_request->expects(
-            $this->at(4)
-        )->method(
-                'getParam'
-            )->with(
-                'js_order'
-            )->will(
-                $this->returnValue($jsOrder)
-            );
-        $this->_request->expects($this->once(5))->method('getPost')->will($this->returnValue(true));
-
-        $themeMock = $this->getMock(
-            'Magento\Core\Model\Theme',
-            array('save', 'load', 'setCustomization', 'getThemeImage', '__wakeup'),
-            array(),
-            '',
-            false
-        );
-
-        $themeImage = $this->getMock('Magento\Core\Model\Theme\Image', array(), array(), '', false);
-        $themeMock->expects($this->any())->method('getThemeImage')->will($this->returnValue($themeImage));
-
-        $themeFactory = $this->getMock(
-            'Magento\Framework\View\Design\Theme\FlyweightFactory',
-            array('create'),
-            array(),
-            '',
-            false
-        );
-        $themeFactory->expects($this->once())->method('create')->will($this->returnValue($themeMock));
-
-        $this->_objectManagerMock->expects(
-            $this->at(0)
-        )->method(
-                'get'
-            )->with(
-                'Magento\Framework\View\Design\Theme\FlyweightFactory'
-            )->will(
-                $this->returnValue($themeFactory)
-            );
-
-        $this->_objectManagerMock->expects(
-            $this->at(1)
-        )->method(
-                'get'
-            )->with(
-                'Magento\Theme\Model\Theme\Customization\File\CustomCss'
-            )->will(
-                $this->returnValue(null)
-            );
-
-        $this->_objectManagerMock->expects(
-            $this->at(2)
-        )->method(
-                'create'
-            )->with(
-                'Magento\Theme\Model\Theme\SingleFile'
-            )->will(
-                $this->returnValue(null)
-            );
-
-        $this->_model->saveAction();
-    }
-
-    public function testIndexAction()
-    {
-        $menuModel = $this->getMock('\Magento\Backend\Model\Menu', array(), array(), '', false);
-        $menuModel->expects($this->once())
-            ->method('getParentItems')
-            ->with($this->equalTo('Magento_Theme::system_design_theme'))
-            ->will($this->returnValue(array()));
-
-        $menuBlock = $this->getMock('\Magento\Backend\Block\Menu', array(), array(), '', false);
-        $menuBlock->expects($this->once())
-            ->method('getMenuModel')
-            ->will($this->returnValue($menuModel));
-
-        $layout = $this->getMock('\Magento\Framework\View\LayoutInterface', array(), array(), '', false);
-        $layout->expects($this->any())
-            ->method('getBlock')
-            ->with($this->equalTo('menu'))
-            ->will($this->returnValue($menuBlock));
-
-        $this->view->expects($this->once())
-            ->method('getLayout')
-            ->will($this->returnValue($layout));
-
-        $this->eventManager->expects($this->once())
-            ->method('dispatch')
-            ->with($this->equalTo('theme_registration_from_filesystem'))
-            ->will($this->returnValue(null));
-        $this->_model->indexAction();
-    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php b/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
index 8076965079c3c7121f83a8b89dbb77e5aeb90fd3..d3c9935755ed7c96f60c783c42e1b4336010f11f 100644
--- a/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
+++ b/dev/tests/unit/testsuite/Magento/User/Model/UserTest.php
@@ -248,7 +248,7 @@ class UserTest extends \PHPUnit_Framework_TestCase
         );
 
 
-        $this->_model->sendPasswordResetNotificationEmail();
+        $this->assertInstanceOf('\Magento\User\Model\User', $this->_model->sendPasswordResetNotificationEmail());
     }
 
     public function testSendPasswordResetConfirmationEmail()
@@ -337,7 +337,6 @@ class UserTest extends \PHPUnit_Framework_TestCase
             $this->returnValue($this->_storetMock)
         );
 
-
-        $this->_model->sendPasswordResetConfirmationEmail();
+        $this->assertInstanceOf('\Magento\User\Model\User', $this->_model->sendPasswordResetConfirmationEmail());
     }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategyTest.php b/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategyTest.php
index 277147c7d08456cc10e789f6ea2b01b7d2aed883..0f4e2171db72fde9f59f3e73c564782af7071fa9 100644
--- a/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategyTest.php
+++ b/dev/tests/unit/testsuite/Magento/Webapi/Model/Soap/Wsdl/ComplexTypeStrategyTest.php
@@ -98,7 +98,7 @@ class ComplexTypeStrategyTest extends \PHPUnit_Framework_TestCase
 
         $this->_wsdl->expects($this->any())->method('toDomDocument')->will($this->returnValue(new \DOMDocument()));
 
-        $schemaMock = $this->_getDomElementMock();
+        $schemaMock = $this->getMock('DOMElement', [], ['a']);
         $schemaMock->expects($this->any())->method('appendChild');
         $this->_wsdl->expects($this->any())->method('getSchema')->will($this->returnValue($schemaMock));
 
@@ -244,7 +244,7 @@ class ComplexTypeStrategyTest extends \PHPUnit_Framework_TestCase
         );
 
         $this->_wsdl->expects($this->any())->method('toDomDocument')->will($this->returnValue(new \DOMDocument()));
-        $schemaMock = $this->_getDomElementMock();
+        $schemaMock = $this->getMock('DOMElement', [], ['a']);
         $schemaMock->expects($this->any())->method('appendChild');
         $this->_wsdl->expects($this->any())->method('getSchema')->will($this->returnValue($schemaMock));
         $this->_typeProcessor->expects(
@@ -285,14 +285,4 @@ class ComplexTypeStrategyTest extends \PHPUnit_Framework_TestCase
             $complexType->getElementsByTagName("xsd:documentation")->item(0)->nodeValue
         );
     }
-
-    /**
-     * Create mock for DOMElement.
-     *
-     * @return \PHPUnit_Framework_MockObject_MockObject
-     */
-    protected function _getDomElementMock()
-    {
-        return $this->getMockBuilder('DOMElement')->disableOriginalConstructor()->getMock();
-    }
 }
diff --git a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php
index 83871288b2fd61d17b7c7e9f022497ee81f848d7..54ea80cd854745bae0c529aad993ce3be93cc37f 100644
--- a/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php
+++ b/dev/tests/unit/testsuite/Magento/Weee/Model/Total/Quote/WeeeTest.php
@@ -200,7 +200,7 @@ class WeeeTest extends \PHPUnit_Framework_TestCase
         $arguments = [
             'taxData' => $taxHelper,
             'calculation' => $calculator,
-            '_weeeData' => $weeeHelper,
+            'weeeData' => $weeeHelper,
         ];
 
         $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
@@ -264,8 +264,8 @@ class WeeeTest extends \PHPUnit_Framework_TestCase
             'address_data' => [
                 'subtotal_incl_tax' => 20,
                 'base_subtotal_incl_tax' => 20,
-                'subtotal' => 18.48,
-                'base_subtotal' => 18.48,
+                'weee' => 18.48,
+                'base_weee' => 18.48,
                 'extra_tax_amount' => 0,
                 'base_extra_tax_amount' => 0,
             ]
@@ -314,8 +314,8 @@ class WeeeTest extends \PHPUnit_Framework_TestCase
                 'base_subtotal_incl_tax' => 20,
                 'subtotal' => 0,
                 'base_subtotal' => 0,
-                'extra_tax_amount' => 18.48,
-                'base_extra_tax_amount' => 18.48,
+                'weee_amount' => 18.48,
+                'base_weee_amount' => 18.48,
             ]
         ];
 
@@ -400,10 +400,10 @@ class WeeeTest extends \PHPUnit_Framework_TestCase
             'address_data' => [
                 'subtotal_incl_tax' => 20,
                 'base_subtotal_incl_tax' => 20,
-                'subtotal' => 18.48,
-                'base_subtotal' => 18.48,
-                'extra_tax_amount' => 0,
-                'base_extra_tax_amount' => 0,
+                'extra_subtotal_amount' => 18.48,
+                'base_extra_subtotal_amount' => 18.48,
+                'extra_tax_amount' => 1.52,
+                'base_extra_tax_amount' => 1.52,
             ]
         ];
 
@@ -647,4 +647,4 @@ class WeeeTest extends \PHPUnit_Framework_TestCase
         ];
         return $data;
     }
-}
+}
\ No newline at end of file
diff --git a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/IndexTest.php b/dev/tests/unit/testsuite/Magento/Wishlist/Controller/IndexTest.php
deleted file mode 100644
index 6240b30af26abc139a29bdd57fbfa594995daeb4..0000000000000000000000000000000000000000
--- a/dev/tests/unit/testsuite/Magento/Wishlist/Controller/IndexTest.php
+++ /dev/null
@@ -1,167 +0,0 @@
-<?php
-/**
- * Magento
- *
- * NOTICE OF LICENSE
- *
- * This source file is subject to the Open Software License (OSL 3.0)
- * that is bundled with this package in the file LICENSE.txt.
- * It is also available through the world-wide-web at this URL:
- * http://opensource.org/licenses/osl-3.0.php
- * If you did not receive a copy of the license and are unable to
- * obtain it through the world-wide-web, please send an email
- * to license@magentocommerce.com so we can send you a copy immediately.
- *
- * DISCLAIMER
- *
- * Do not edit or add to this file if you wish to upgrade Magento to newer
- * versions in the future. If you wish to customize Magento for your
- * needs please refer to http://www.magentocommerce.com for more information.
- *
- * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
- * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
- */
-namespace Magento\Wishlist\Controller;
-
-class IndexTest extends \PHPUnit_Framework_TestCase
-{
-    public function testControllerImplementsProductViewInterface()
-    {
-        $this->assertInstanceOf(
-            'Magento\Catalog\Controller\Product\View\ViewInterface',
-            $this->getMock('Magento\Wishlist\Controller\Index', array(), array(), '', false)
-        );
-    }
-
-    public function testCartAction()
-    {
-        $request = $this->getMock('Magento\Framework\App\Request\Http', array(), array(), '', false);
-        $response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
-
-        $wishlistItem = $this->getMock(
-            'Magento\Framework\Object',
-            array('load', 'getId', 'mergeBuyRequest', 'addToCart', 'getProduct'),
-            array(),
-            '',
-            false
-        );
-        $wishlistItem->expects($this->once())->method('load')->will($this->returnValue($wishlistItem));
-        $wishlistItem->expects($this->once())->method('getId')->will($this->returnValue(1));
-        $wishlistItem->expects($this->once())->method('getProduct')->will($this->returnValue($wishlistItem));
-
-        $objectManager = $this->getMock('Magento\Framework\ObjectManager');
-
-        $locale = $this->getMock('Magento\Framework\Locale\Resolver', array(), array(), '', false);
-
-        $optionCollection = $this->getMock(
-            'Magento\Wishlist\Model\Resource\Item\Option\Collection',
-            array('addItemFilter', 'getOptionsByItem'),
-            array(),
-            '',
-            false
-        );
-        $optionCollection->expects(
-            $this->once()
-        )->method(
-            'addItemFilter'
-        )->will(
-            $this->returnValue($optionCollection)
-        );
-
-        $cart = $this->getMock(
-            'Magento\Checkout\Model\Cart',
-            array('save', 'getQuote', 'collectTotals'),
-            array(),
-            '',
-            false
-        );
-        $cart->expects($this->once())->method('save')->will($this->returnValue($cart));
-        $cart->expects($this->any())->method('getQuote')->will($this->returnValue($cart));
-
-        $option = $this->getMock('Magento\Framework\Object', array('getCollection'), array(), '', false);
-        $option->expects($this->once())->method('getCollection')->will($this->returnValue($optionCollection));
-
-        $product = $this->getMock('Magento\Catalog\Helper\Product', array(), array(), '', false);
-
-        $escaper = $this->getMock('Magento\Excaper', array('escapeHtml'), array(), '', false);
-
-        $wishlistHelper = $this->getMock(
-            'Magento\Wishlist\Helper\Data',
-            array('getShouldRedirectToCart', 'calculate', 'getCustomer'),
-            array(),
-            '',
-            false
-        );
-
-        $mapGet = array(
-            array('Magento\Framework\Locale\ResolverInterface', $locale),
-            array('Magento\Checkout\Model\Cart', $cart),
-            array('Magento\Catalog\Helper\Product', $product),
-            array('Magento\Framework\Escaper', $escaper),
-            array('Magento\Wishlist\Helper\Data', $wishlistHelper),
-            array('Magento\Checkout\Helper\Cart', $wishlistHelper)
-        );
-
-        $mapCreate = array(
-            array('Magento\Wishlist\Model\Item', array(), $wishlistItem),
-            array('Magento\Wishlist\Model\Item\Option', array(), $option)
-        );
-
-        $objectManager->expects($this->any())->method('get')->will($this->returnValueMap($mapGet));
-        $objectManager->expects($this->any())->method('create')->will($this->returnValueMap($mapCreate));
-
-        $controller = $this->_factory($request, $response, $objectManager);
-
-        $controller->cartAction();
-    }
-
-    /**
-     * Create the tested object
-     *
-     * @param \Magento\Framework\App\Request\Http $request
-     * @param \Magento\Framework\App\Response\Http|null $response
-     * @param \Magento\Framework\ObjectManager|null $objectManager
-     * @return \Magento\Wishlist\Controller\Index
-     */
-    protected function _factory($request, $response = null, $objectManager = null)
-    {
-        if (!$response) {
-            /** @var $response \Magento\Framework\App\ResponseInterface */
-            $response = $this->getMock('Magento\Framework\App\Response\Http', array(), array(), '', false);
-            $response->headersSentThrowsException = false;
-        }
-        if (!$objectManager) {
-            $config = new \Magento\Framework\ObjectManager\Config\Config();
-            $factory = new \Magento\Framework\ObjectManager\Factory\Factory($config);
-            $objectManager = new \Magento\Framework\ObjectManager\ObjectManager($factory, $config);
-        }
-        $rewriteFactory = $this->getMock(
-            'Magento\UrlRewrite\Model\UrlRewriteFactory', array('create'), array(), '', false
-        );
-        $helper = new \Magento\TestFramework\Helper\ObjectManager($this);
-        $varienFront = $helper->getObject(
-            'Magento\Framework\App\FrontController',
-            array('rewriteFactory' => $rewriteFactory)
-        );
-
-        $arguments = array(
-            'request' => $request,
-            'response' => $response,
-            'objectManager' => $objectManager,
-            'frontController' => $varienFront
-        );
-        $context = $helper->getObject('Magento\Backend\App\Action\Context', $arguments);
-
-        $wishlistModel = $this->getMock('\Magento\Wishlist\Model\Wishlist', array(), array(), '', false);
-
-        $coreRegistry = $this->getMock('\Magento\Framework\Registry', array('registry'), array(), '', false);
-        $coreRegistry->expects($this->once())->method('registry')->will($this->returnValue($wishlistModel));
-
-        $messageManager = $this->getMock('\Magento\Framework\Message\Manager', array(), array(), '', false);
-
-        return $helper->getObject(
-            'Magento\Wishlist\Controller\Index',
-            array('context' => $context, 'coreRegistry' => $coreRegistry, 'messageManager' => $messageManager)
-        );
-    }
-}
diff --git a/downloader/index.php b/downloader/index.php
index ddee3ef2289806af81cec942d931c695582bd5d6..03e7db5ec1e30b204c9336c5237dd2c4d4d6a57e 100644
--- a/downloader/index.php
+++ b/downloader/index.php
@@ -23,7 +23,7 @@
  */
 
 if (version_compare(phpversion(), '5.4.0', '<') === true) {
-    echo  '<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;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.4.0 or newer. <a href="http://www.magentocommerce.com/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
+    echo  '<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;">Whoops, it looks like you have an invalid PHP version.</h3></div><p>Magento supports PHP 5.4.0 or newer. <a href="http://www.magentocommerce.com/magento2/install" target="">Find out</a> how to install</a> Magento using PHP-CGI as a work-around.</p></div>';
     exit;
 }
 
diff --git a/downloader/template/install/header.phtml b/downloader/template/install/header.phtml
index fc9b87297c8594aae61c924335c002108f5903d8..b7b1208120facdb4707233af3bbcd41d9e198452 100644
--- a/downloader/template/install/header.phtml
+++ b/downloader/template/install/header.phtml
@@ -83,7 +83,7 @@
 
 <br/>
 <p>
-    Having trouble installing Magento?    Check out our <a href="http://www.magentocommerce.com/install" id="installation_guide_link">Installation Guide</a>
+    Having trouble installing Magento?    Check out our <a href="http://www.magentocommerce.com/magento2/install" id="installation_guide_link">Installation Guide</a>
     <script type="text/javascript">
         $('installation_guide_link').target = "installation_guide";
     </script>
diff --git a/lib/internal/Magento/Framework/App/Action/Action.php b/lib/internal/Magento/Framework/App/Action/Action.php
index 18bd9300b9da47c2b1b4bc77fe8155fd2e4c1c94..750c9a42ac73c771682915428740f17381cd5d62 100644
--- a/lib/internal/Magento/Framework/App/Action/Action.php
+++ b/lib/internal/Magento/Framework/App/Action/Action.php
@@ -30,16 +30,6 @@ use Magento\Framework\App\ResponseInterface;
 
 class Action extends AbstractAction
 {
-    const FLAG_NO_DISPATCH = 'no-dispatch';
-
-    const FLAG_NO_POST_DISPATCH = 'no-postDispatch';
-
-    const FLAG_NO_DISPATCH_BLOCK_EVENT = 'no-beforeGenerateLayoutBlocksDispatch';
-
-    const PARAM_NAME_BASE64_URL = 'r64';
-
-    const PARAM_NAME_URL_ENCODED = 'uenc';
-
     /**
      * @var \Magento\Framework\ObjectManager
      */
@@ -120,8 +110,7 @@ class Action extends AbstractAction
 
         if ($request->isDispatched() && !$this->_actionFlag->get('', self::FLAG_NO_DISPATCH)) {
             \Magento\Framework\Profiler::start('action_body');
-            $actionMethodName = $request->getActionName() . 'Action';
-            $this->{$actionMethodName}();
+            $this->execute();
             \Magento\Framework\Profiler::start('postdispatch');
             if (!$this->_actionFlag->get('', self::FLAG_NO_POST_DISPATCH)) {
                 $this->_eventManager->dispatch(
@@ -185,4 +174,12 @@ class Action extends AbstractAction
         $this->_redirect->redirect($this->getResponse(), $path, $arguments);
         return $this->getResponse();
     }
+    
+    /**
+     * @return \Magento\Framework\App\ActionFlag
+     */
+    public function getActionFlag()
+    {
+        return $this->_actionFlag;
+    }
 }
diff --git a/lib/internal/Magento/Framework/App/ActionFactory.php b/lib/internal/Magento/Framework/App/ActionFactory.php
index 29f43ddf3c643fea316346124b0cfeb4c295dfcc..297c5fe37072b4ac05c914dd0f1133bdcda0fecc 100644
--- a/lib/internal/Magento/Framework/App/ActionFactory.php
+++ b/lib/internal/Magento/Framework/App/ActionFactory.php
@@ -25,7 +25,7 @@
  */
 namespace Magento\Framework\App;
 
-use Magento\Framework\App\Action\AbstractAction;
+use Magento\Framework\App\ActionInterface;
 
 class ActionFactory
 {
@@ -43,14 +43,20 @@ class ActionFactory
     }
 
     /**
-     * @param string $controllerName
+     * Create action
+     *
+     * @param string $actionName
      * @param array $arguments
-     * @return AbstractAction
+     * @return ActionInterface
+     * @throws \InvalidArgumentException
      */
-    public function createController($controllerName, array $arguments = array())
+    public function create($actionName, array $arguments = array())
     {
+        if (!is_subclass_of($actionName, '\Magento\Framework\App\ActionInterface')) {
+            throw new \InvalidArgumentException('Invalid action name provided');
+        }
         $context = $this->_objectManager->create('Magento\Framework\App\Action\Context', $arguments);
         $arguments['context'] = $context;
-        return $this->_objectManager->create($controllerName, $arguments);
+        return $this->_objectManager->create($actionName, $arguments);
     }
 }
diff --git a/lib/internal/Magento/Framework/App/ActionInterface.php b/lib/internal/Magento/Framework/App/ActionInterface.php
index fe65dfac869645316ce0131716c6500fbc3c2999..172442c286d8955f5c1c5177b38ab9cff3f691af 100644
--- a/lib/internal/Magento/Framework/App/ActionInterface.php
+++ b/lib/internal/Magento/Framework/App/ActionInterface.php
@@ -27,11 +27,22 @@ namespace Magento\Framework\App;
 
 interface ActionInterface
 {
+    const FLAG_NO_DISPATCH = 'no-dispatch';
+
+    const FLAG_NO_POST_DISPATCH = 'no-postDispatch';
+
+    const FLAG_NO_DISPATCH_BLOCK_EVENT = 'no-beforeGenerateLayoutBlocksDispatch';
+
+    const PARAM_NAME_BASE64_URL = 'r64';
+
+    const PARAM_NAME_URL_ENCODED = 'uenc';
+
     /**
      * Dispatch request
      *
      * @param RequestInterface $request
      * @return ResponseInterface
+     * @throws Action\NotFoundException
      */
     public function dispatch(RequestInterface $request);
 
diff --git a/lib/internal/Magento/Framework/App/Router/ActionList.php b/lib/internal/Magento/Framework/App/Router/ActionList.php
new file mode 100644
index 0000000000000000000000000000000000000000..db18a7b304977acfdb3d72a636bd43c3d410992f
--- /dev/null
+++ b/lib/internal/Magento/Framework/App/Router/ActionList.php
@@ -0,0 +1,91 @@
+<?php
+/**
+ *
+ * Magento
+ *
+ * NOTICE OF LICENSE
+ *
+ * This source file is subject to the Open Software License (OSL 3.0)
+ * that is bundled with this package in the file LICENSE.txt.
+ * It is also available through the world-wide-web at this URL:
+ * http://opensource.org/licenses/osl-3.0.php
+ * If you did not receive a copy of the license and are unable to
+ * obtain it through the world-wide-web, please send an email
+ * to license@magentocommerce.com so we can send you a copy immediately.
+ *
+ * DISCLAIMER
+ *
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
+ * versions in the future. If you wish to customize Magento for your
+ * needs please refer to http://www.magentocommerce.com for more information.
+ *
+ * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
+ * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
+ */
+namespace Magento\Framework\App\Router;
+
+class ActionList
+{
+    /**
+     * List of application actions
+     *
+     * @var array
+     */
+    protected $actions;
+
+    /**
+     * @var array
+     */
+    protected $reservedWords;
+
+    /**
+     * @param \Magento\Framework\Config\CacheInterface $cache
+     * @param ActionList\Reader $actionReader
+     * @param string $actionInterface
+     * @param string $cacheKey
+     * @param array $reservedWords
+     */
+    public function __construct(
+        \Magento\Framework\Config\CacheInterface $cache,
+        ActionList\Reader $actionReader,
+        $actionInterface = '\Magento\Framework\App\ActionInterface',
+        $cacheKey = 'app_action_list',
+        $reservedWords = array('new', 'switch', 'return', 'print', 'list')
+    ) {
+        $this->reservedWords = $reservedWords;
+        $this->actionInterface = $actionInterface;
+        $data = $cache->load($cacheKey);
+        if (!$data) {
+            $this->actions = $actionReader->read();
+            $cache->save(serialize($this->actions), $cacheKey);
+        } else {
+            $this->actions = unserialize($data);
+        }
+    }
+
+    /**
+     * Retrieve action class
+     *
+     * @param string $module
+     * @param string $area
+     * @param string $namespace
+     * @param string $action
+     * @return null|string
+     */
+    public function get($module, $area, $namespace, $action)
+    {
+        if ($area) {
+            $area = '\\' . $area;
+        }
+        if (in_array(strtolower($action), $this->reservedWords)) {
+            $action .= 'action';
+        }
+        $fullPath = str_replace('_', '\\', strtolower(
+            $module . '\\controller' . $area . '\\' . $namespace . '\\' . $action
+        ));
+        if (isset($this->actions[$fullPath])) {
+            return is_subclass_of($this->actions[$fullPath], $this->actionInterface) ? $this->actions[$fullPath] : null;
+        }
+        return null;
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Config/Source/TaxClass/Product.php b/lib/internal/Magento/Framework/App/Router/ActionList/Reader.php
similarity index 58%
rename from app/code/Magento/Tax/Model/Config/Source/TaxClass/Product.php
rename to lib/internal/Magento/Framework/App/Router/ActionList/Reader.php
index 830f45d82a49c64571d70eef08fd971598addf10..9d2d7e4f0a4de72c7f7aa8c7108df3964553fa07 100644
--- a/app/code/Magento/Tax/Model/Config/Source/TaxClass/Product.php
+++ b/lib/internal/Magento/Framework/App/Router/ActionList/Reader.php
@@ -1,5 +1,6 @@
 <?php
 /**
+ *
  * Magento
  *
  * NOTICE OF LICENSE
@@ -21,32 +22,36 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Tax\Model\Config\Source\TaxClass;
+namespace Magento\Framework\App\Router\ActionList;
 
-class Product implements \Magento\Framework\Option\ArrayInterface
+class Reader
 {
     /**
-     * @var \Magento\Tax\Model\TaxClass\Source\ProductFactory
+     * @var \Magento\Framework\Module\Dir\Reader
      */
-    protected $_productFactory;
+    protected $moduleReader;
 
     /**
-     * @param \Magento\Tax\Model\TaxClass\Source\ProductFactory $productFactory
+     * @param \Magento\Framework\Module\Dir\Reader $moduleReader
      */
-    public function __construct(\Magento\Tax\Model\TaxClass\Source\ProductFactory $productFactory)
+    public function __construct(\Magento\Framework\Module\Dir\Reader $moduleReader)
     {
-        $this->_productFactory = $productFactory;
+        $this->moduleReader = $moduleReader;
     }
 
     /**
-     * Retrieve list of products
+     * Read list of all available application actions
      *
      * @return array
      */
-    public function toOptionArray()
+    public function read()
     {
-        /** @var $sourceProduct \Magento\Tax\Model\TaxClass\Source\Product */
-        $sourceProduct = $this->_productFactory->create();
-        return $sourceProduct->toOptionArray();
+        $actionFiles = $this->moduleReader->getActionFiles();
+        $actions = array();
+        foreach ($actionFiles as $actionFile) {
+            $action = str_replace('/', '\\', substr($actionFile, 0, -4));
+            $actions[strtolower($action)] = $action;
+        }
+        return $actions;
     }
 }
diff --git a/lib/internal/Magento/Framework/App/Router/DefaultRouter.php b/lib/internal/Magento/Framework/App/Router/DefaultRouter.php
index 26ebec0935591b8fa0bf081a7e19f564396a7645..22510fcd270c14603751b261f8f7fa78a1977534 100644
--- a/lib/internal/Magento/Framework/App/Router/DefaultRouter.php
+++ b/lib/internal/Magento/Framework/App/Router/DefaultRouter.php
@@ -27,13 +27,19 @@ namespace Magento\Framework\App\Router;
 
 use Magento\Framework\App\ActionFactory;
 use Magento\Framework\App\RequestInterface;
+use Magento\Framework\App\RouterInterface;
 
-class DefaultRouter extends AbstractRouter
+class DefaultRouter implements RouterInterface
 {
     /**
      * @var NoRouteHandlerList
      */
-    protected $_noRouteHandlerList;
+    protected $noRouteHandlerList;
+
+    /**
+     * @var ActionFactory
+     */
+    protected $actionFactory;
 
     /**
      * @param ActionFactory $actionFactory
@@ -41,8 +47,8 @@ class DefaultRouter extends AbstractRouter
      */
     public function __construct(ActionFactory $actionFactory, NoRouteHandlerList $noRouteHandlerList)
     {
-        parent::__construct($actionFactory);
-        $this->_noRouteHandlerList = $noRouteHandlerList;
+        $this->actionFactory = $actionFactory;
+        $this->noRouteHandlerList = $noRouteHandlerList;
     }
 
     /**
@@ -53,15 +59,12 @@ class DefaultRouter extends AbstractRouter
      */
     public function match(RequestInterface $request)
     {
-        foreach ($this->_noRouteHandlerList->getHandlers() as $noRouteHandler) {
+        foreach ($this->noRouteHandlerList->getHandlers() as $noRouteHandler) {
             if ($noRouteHandler->process($request)) {
                 break;
             }
         }
 
-        return $this->_actionFactory->createController(
-            'Magento\Framework\App\Action\Forward',
-            array('request' => $request)
-        );
+        return $this->actionFactory->create('Magento\Framework\App\Action\Forward', array('request' => $request));
     }
 }
diff --git a/lib/internal/Magento/Framework/App/View.php b/lib/internal/Magento/Framework/App/View.php
index 055c9320e801828256b7c83a89e1747413b1860e..8eb0420c95b1036b512d647f437a843fb3f2c419 100644
--- a/lib/internal/Magento/Framework/App/View.php
+++ b/lib/internal/Magento/Framework/App/View.php
@@ -103,15 +103,9 @@ class View implements ViewInterface
     }
 
     /**
-     * Load layout by handles(s)
-     *
-     * @param   string|null|bool $handles
-     * @param   bool $generateBlocks
-     * @param   bool $generateXml
-     * @return  $this
-     * @throws  \RuntimeException
+     * {@inheritdoc}
      */
-    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true)
+    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true, $addActionHandles = true)
     {
         if ($this->_isLayoutLoaded) {
             throw new \RuntimeException('Layout must be loaded only once.');
@@ -121,9 +115,10 @@ class View implements ViewInterface
             $this->getLayout()->getUpdate()->addHandle($handles ? $handles : 'default');
         }
 
-        // add default layout handles for this action
-        $this->addActionLayoutHandles();
-
+        if ($addActionHandles) {
+            // add default layout handles for this action
+            $this->addActionLayoutHandles();
+        }
         $this->loadLayoutUpdates();
 
         if (!$generateXml) {
diff --git a/lib/internal/Magento/Framework/App/ViewInterface.php b/lib/internal/Magento/Framework/App/ViewInterface.php
index 353b5b800471baef43c7729a9d1da893cc25fcbb..985c00b9134054ec510040aa5dd85cf142f09a49 100644
--- a/lib/internal/Magento/Framework/App/ViewInterface.php
+++ b/lib/internal/Magento/Framework/App/ViewInterface.php
@@ -53,10 +53,11 @@ interface ViewInterface
      * @param   string|null|bool $handles
      * @param   bool $generateBlocks
      * @param   bool $generateXml
+     * @param   bool $addActionHandles
      * @return  ViewInterface
      * @throws  \RuntimeException
      */
-    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true);
+    public function loadLayout($handles = null, $generateBlocks = true, $generateXml = true, $addActionHandles = true);
 
     /**
      * Generate layout xml
diff --git a/lib/internal/Magento/Framework/AppInterface.php b/lib/internal/Magento/Framework/AppInterface.php
index cf404e816676594abd2304c2086e0ad151b0870c..a51c3246ce9ea94ad37dee28bf1893c2f28e2975 100644
--- a/lib/internal/Magento/Framework/AppInterface.php
+++ b/lib/internal/Magento/Framework/AppInterface.php
@@ -35,7 +35,7 @@ interface AppInterface
     /**
      * Magento version
      */
-    const VERSION = '2.0.0.0-dev86';
+    const VERSION = '2.0.0.0-dev87';
 
     /**
      * Launch application
diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php
index 571f3da8d9795367e1e7d2c1812b8c37aa894dd2..b472896d44e5a7485c91bb26112ea5b14c6189d2 100644
--- a/lib/internal/Magento/Framework/Data/Collection.php
+++ b/lib/internal/Magento/Framework/Data/Collection.php
@@ -693,6 +693,18 @@ class Collection implements \IteratorAggregate, \Countable, \Magento\Framework\O
         return $this->loadData($printQuery, $logQuery);
     }
 
+    /**
+     * Load data with filter in place
+     *
+     * @param bool $printQuery
+     * @param bool $logQuery
+     * @return $this
+     */
+    public function loadWithFilter($printQuery = false, $logQuery = false)
+    {
+        return $this->loadData($printQuery, $logQuery);
+    }
+
     /**
      * Convert collection to XML
      *
diff --git a/lib/internal/Magento/Framework/Data/Collection/Db.php b/lib/internal/Magento/Framework/Data/Collection/Db.php
index 92010867bec340cd001a06f27ce6dd991b78baa9..7ec6ccf76c9058803f98344f1afbc176e91413e9 100644
--- a/lib/internal/Magento/Framework/Data/Collection/Db.php
+++ b/lib/internal/Magento/Framework/Data/Collection/Db.php
@@ -552,14 +552,23 @@ class Db extends \Magento\Framework\Data\Collection
             return $this;
         }
 
-        $this->_beforeLoad();
+        return $this->loadWithFilter($printQuery, $logQuery);
+    }
 
+    /**
+     * Load data with filter in place
+     *
+     * @param   bool $printQuery
+     * @param   bool $logQuery
+     * @return  $this
+     */
+    public function loadWithFilter($printQuery = false, $logQuery = false)
+    {
+        $this->_beforeLoad();
         $this->_renderFilters()->_renderOrders()->_renderLimit();
-
         $this->printLogQuery($printQuery, $logQuery);
         $data = $this->getData();
         $this->resetData();
-
         if (is_array($data)) {
             foreach ($data as $row) {
                 $item = $this->getNewEmptyItem();
@@ -570,7 +579,6 @@ class Db extends \Magento\Framework\Data\Collection
                 $this->addItem($item);
             }
         }
-
         $this->_setIsLoaded();
         $this->_afterLoad();
         return $this;
diff --git a/lib/internal/Magento/Framework/Model/AbstractModel.php b/lib/internal/Magento/Framework/Model/AbstractModel.php
index ccf03d36baca719f2e09111821033dcece7c5b12..1954871119059bfe0387598c699f4808d6f09c57 100644
--- a/lib/internal/Magento/Framework/Model/AbstractModel.php
+++ b/lib/internal/Magento/Framework/Model/AbstractModel.php
@@ -673,7 +673,7 @@ abstract class AbstractModel extends \Magento\Framework\Object
      *
      * @return $this
      */
-    final public function clearInstance()
+    public function clearInstance()
     {
         $this->_clearReferences();
         $this->_eventManager->dispatch($this->_eventPrefix . '_clear', $this->_getEventData());
diff --git a/lib/internal/Magento/Framework/Module/Dir.php b/lib/internal/Magento/Framework/Module/Dir.php
index 86e9a3963d3849a2768a264efc3b50d3c3eae395..964197f80cb551da767ef0d56a95a07b8edd37e1 100644
--- a/lib/internal/Magento/Framework/Module/Dir.php
+++ b/lib/internal/Magento/Framework/Module/Dir.php
@@ -64,7 +64,7 @@ class Dir
     {
         $path = $this->_string->upperCaseWords($moduleName, '_', '/');
         if ($type) {
-            if (!in_array($type, array('etc', 'sql', 'data', 'i18n', 'view'))) {
+            if (!in_array($type, array('etc', 'sql', 'data', 'i18n', 'view', 'Controller'))) {
                 throw new \InvalidArgumentException("Directory type '{$type}' is not recognized.");
             }
             $path .= '/' . $type;
diff --git a/lib/internal/Magento/Framework/Module/Dir/Reader.php b/lib/internal/Magento/Framework/Module/Dir/Reader.php
index 36690570614d8cea8a765995a125ec1cee6db0b5..db88b5c0d6b4aa3a75e852b0d75f0319913ca8cc 100644
--- a/lib/internal/Magento/Framework/Module/Dir/Reader.php
+++ b/lib/internal/Magento/Framework/Module/Dir/Reader.php
@@ -102,6 +102,29 @@ class Reader
         return $this->fileIteratorFactory->create($this->modulesDirectory, $result);
     }
 
+    /**
+     * Retrieve list of module action files
+     *
+     * @return array
+     */
+    public function getActionFiles()
+    {
+        $actions = array();
+        foreach (array_keys($this->modulesList->getModules()) as $moduleName) {
+            $actionDir = $this->getModuleDir('Controller', $moduleName);
+            if (!file_exists($actionDir)) {
+                continue;
+            }
+            $dirIterator = new \RecursiveDirectoryIterator($actionDir, \RecursiveDirectoryIterator::SKIP_DOTS);
+            $recursiveIterator = new \RecursiveIteratorIterator($dirIterator, \RecursiveIteratorIterator::LEAVES_ONLY);
+            /** @var \SplFileInfo $actionFile */
+            foreach ($recursiveIterator as $actionFile) {
+                $actions[] = $this->modulesDirectory->getRelativePath($actionFile->getPathname());
+            }
+        }
+        return $actions;
+    }
+
     /**
      * Get module directory by directory type
      *
diff --git a/lib/internal/Magento/Framework/Module/etc/module.xsd b/lib/internal/Magento/Framework/Module/etc/module.xsd
index 913bc99678c64880f64f55fec69c025c032a79d6..b7d079b532948b18a5c839595668cc352647bd26 100644
--- a/lib/internal/Magento/Framework/Module/etc/module.xsd
+++ b/lib/internal/Magento/Framework/Module/etc/module.xsd
@@ -158,7 +158,7 @@
             </xs:documentation>
         </xs:annotation>
         <xs:restriction base="xs:string">
-            <xs:pattern value="[A-Z]+[a-z0-9]{1,}_[A-Z]+[A-Z0-9a-z]{1,}" />
+            <xs:pattern value="[A-Z]+[A-Za-z0-9]{1,}_[A-Z]+[A-Z0-9a-z]{1,}" />
         </xs:restriction>
     </xs:simpleType>
 
diff --git a/app/code/Magento/Customer/Model/Resource/AbstractServiceCollection.php b/lib/internal/Magento/Framework/Service/AbstractServiceCollection.php
similarity index 96%
rename from app/code/Magento/Customer/Model/Resource/AbstractServiceCollection.php
rename to lib/internal/Magento/Framework/Service/AbstractServiceCollection.php
index e7efe26ef58d1dc81a26d4087dad11105c0a578b..12d5ef8c4a701e1327a4d6936caa39d1a481a29b 100644
--- a/app/code/Magento/Customer/Model/Resource/AbstractServiceCollection.php
+++ b/lib/internal/Magento/Framework/Service/AbstractServiceCollection.php
@@ -21,9 +21,10 @@
  * @copyright   Copyright (c) 2014 X.commerce, Inc. (http://www.magentocommerce.com)
  * @license     http://opensource.org/licenses/osl-3.0.php  Open Software License (OSL 3.0)
  */
-namespace Magento\Customer\Model\Resource;
 
-use Magento\Core\Model\EntityFactory;
+namespace Magento\Framework\Service;
+
+use Magento\Framework\Data\Collection\EntityFactoryInterface;
 use Magento\Framework\Service\V1\Data\Filter;
 use Magento\Framework\Service\V1\Data\FilterBuilder;
 use Magento\Framework\Service\V1\Data\SearchCriteria;
@@ -31,7 +32,7 @@ use Magento\Framework\Service\V1\Data\SearchCriteriaBuilder;
 use Magento\Framework\Exception;
 
 /**
- * Base for customer service collections
+ * Base for service collections
  */
 abstract class AbstractServiceCollection extends \Magento\Framework\Data\Collection
 {
@@ -62,12 +63,12 @@ abstract class AbstractServiceCollection extends \Magento\Framework\Data\Collect
     protected $searchCriteriaBuilder;
 
     /**
-     * @param EntityFactory $entityFactory
+     * @param EntityFactoryInterface $entityFactory
      * @param FilterBuilder $filterBuilder
      * @param SearchCriteriaBuilder $searchCriteriaBuilder
      */
     public function __construct(
-        EntityFactory $entityFactory,
+        EntityFactoryInterface $entityFactory,
         FilterBuilder $filterBuilder,
         SearchCriteriaBuilder $searchCriteriaBuilder
     ) {
diff --git a/lib/internal/Magento/Framework/Translate/Inline.php b/lib/internal/Magento/Framework/Translate/Inline.php
index debea7724b52093ff7c06927be6d230669b2c9ff..008bea227bb8c858ecb91ff775d76fe9e3f54650 100644
--- a/lib/internal/Magento/Framework/Translate/Inline.php
+++ b/lib/internal/Magento/Framework/Translate/Inline.php
@@ -157,7 +157,7 @@ class Inline implements \Magento\Framework\Translate\InlineInterface
      */
     public function processResponseBody(&$body, $isJson = false)
     {
-        if ($this->scope == 'admin' && !$this->isAllowed()) {
+        if (!$this->isAllowed()) {
             $this->stripInlineTranslations($body);
             return $this;
         }
diff --git a/lib/internal/Magento/Framework/Url.php b/lib/internal/Magento/Framework/Url.php
index 6d6e9a5f6c0a8dcccae434f8973dc7c366ac69db..36fc18aec34e28b2da40f9b59659df4f7a3328ce 100644
--- a/lib/internal/Magento/Framework/Url.php
+++ b/lib/internal/Magento/Framework/Url.php
@@ -402,6 +402,11 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
      */
     public function getBaseUrl($params = array())
     {
+        /**
+         *  Original Scope
+         */
+        $origScope = $this->_getScope();
+
         if (isset($params['_scope'])) {
             $this->setScope($params['_scope']);
         }
@@ -425,6 +430,8 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
         }
 
         $result = $this->_getScope()->getBaseUrl($this->_getType(), $this->_isSecure());
+        // setting back the original scope
+        $this->setScope($origScope);
         $this->_routeParamsResolver->setType(self::DEFAULT_URL_TYPE);
         return $result;
     }
@@ -692,7 +699,7 @@ class Url extends \Magento\Framework\Object implements \Magento\Framework\UrlInt
             $this->_setRouteParams($routeParams, false);
         }
 
-        return $this->getBaseUrl() . $this->_getRoutePath($routeParams);
+        return $this->getBaseUrl($routeParams) . $this->_getRoutePath($routeParams);
     }
 
     /**
diff --git a/lib/internal/Magento/Framework/View/Asset/MergeService.php b/lib/internal/Magento/Framework/View/Asset/MergeService.php
index a74b6c5569809ada12cddef07dee38b95cfbb9bb..250064eed6405f8bf2622409b81abb4d75bb5267 100644
--- a/lib/internal/Magento/Framework/View/Asset/MergeService.php
+++ b/lib/internal/Magento/Framework/View/Asset/MergeService.php
@@ -79,7 +79,7 @@ class MergeService
     /**
      * Return merged assets, if merging is enabled for a given content type
      *
-     * @param array $assets
+     * @param MergeableInterface[] $assets
      * @param string $contentType
      * @return array|\Iterator
      * @throws \InvalidArgumentException
diff --git a/lib/internal/Magento/Framework/View/Asset/Merged.php b/lib/internal/Magento/Framework/View/Asset/Merged.php
index fbb70b8687a147db9674f30b3003afab4eb7d7ee..1593b47b47a8874678c34b1c6c05c812337eb6c0 100644
--- a/lib/internal/Magento/Framework/View/Asset/Merged.php
+++ b/lib/internal/Magento/Framework/View/Asset/Merged.php
@@ -62,7 +62,7 @@ class Merged implements \Iterator
      * @param \Magento\Framework\Logger $logger
      * @param MergeStrategyInterface $mergeStrategy
      * @param \Magento\Framework\View\Asset\Repository $assetRepo
-     * @param array $assets
+     * @param MergeableInterface[] $assets
      * @throws \InvalidArgumentException
      */
     public function __construct(
diff --git a/lib/internal/Magento/Framework/View/Asset/Minified.php b/lib/internal/Magento/Framework/View/Asset/Minified.php
index d28dd89af1ee9a2de7496cb9df2cf093f7f363a7..a7c9a8078ff1e5600524569ce325b82fbc10b5a9 100644
--- a/lib/internal/Magento/Framework/View/Asset/Minified.php
+++ b/lib/internal/Magento/Framework/View/Asset/Minified.php
@@ -26,7 +26,7 @@ namespace Magento\Framework\View\Asset;
 /**
  * Minified page asset
  */
-class Minified implements LocalInterface
+class Minified implements MergeableInterface
 {
     /**#@+
      * Strategies for verifying whether the files need to be minified
diff --git a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
index e84a5d090897e811ede2925d5bca0b074a868480..0098ebe4b1535ebb144f9dd1b18b893869bb1812 100644
--- a/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
+++ b/lib/internal/Magento/Framework/View/Element/AbstractBlock.php
@@ -743,7 +743,7 @@ abstract class AbstractBlock extends \Magento\Framework\Object implements BlockI
      * @param array $params
      * @return string
      */
-    protected function _getNotFoundUrl($route = '', $params = array('_direct' => 'core/index/notfound'))
+    protected function _getNotFoundUrl($route = '', $params = array('_direct' => 'core/index/notFound'))
     {
         return $this->getUrl($route, $params);
     }